kem.c
Go to the documentation of this file.
1 /**
2  * @file kem.c
3  * @brief Key encapsulation mechanism (KEM)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pqc/kem.h"
37 
38 //Check crypto library configuration
39 #if (KEM_SUPPORT == ENABLED)
40 
41 
42 /**
43  * @brief Initialize KEM context
44  * @param[in] context Pointer to the KEM context
45  * @param[in] kemAlgo Key encapsulation mechanism
46  **/
47 
48 void kemInit(KemContext *context, const KemAlgo *kemAlgo)
49 {
50  //Initialize KEM context
51  context->kemAlgo = kemAlgo;
52  context->sk = NULL;
53  context->pk = NULL;
54 }
55 
56 
57 /**
58  * @brief Release KEM context
59  * @param[in] context Pointer to the KEM context
60  **/
61 
62 void kemFree(KemContext *context)
63 {
64  //Valid key encapsulation mechanism?
65  if(context->kemAlgo != NULL)
66  {
67  //Check whether the secret key is valid
68  if(context->sk != NULL)
69  {
70  //Clear secret key
71  osMemset(context->sk, 0, context->kemAlgo->secretKeySize);
72 
73  //Release secret key
74  cryptoFreeMem(context->sk);
75  context->sk = NULL;
76  }
77 
78  //Check whether the public key is valid
79  if(context->pk != NULL)
80  {
81  //Clear public key
82  osMemset(context->pk, 0, context->kemAlgo->publicKeySize);
83 
84  //Release public key
85  cryptoFreeMem(context->pk);
86  context->pk = NULL;
87  }
88  }
89 }
90 
91 
92 /**
93  * @brief Key pair generation
94  * @param[in] context Pointer to the KEM context
95  * @param[in] prngAlgo PRNG algorithm
96  * @param[in] prngContext Pointer to the PRNG context
97  * @return Error code
98  **/
99 
100 error_t kemGenerateKeyPair(KemContext *context, const PrngAlgo *prngAlgo,
101  void *prngContext)
102 {
103  error_t error;
104 
105  //Valid key encapsulation mechanism?
106  if(context->kemAlgo != NULL)
107  {
108  //Allocate a memory buffer to hold the secret key
109  if(context->sk == NULL)
110  {
111  context->sk = cryptoAllocMem(context->kemAlgo->secretKeySize);
112  }
113 
114  //Successful memory allocation?
115  if(context->sk != NULL)
116  {
117  //Allocate a memory buffer to hold the public key
118  if(context->pk == NULL)
119  {
120  context->pk = cryptoAllocMem(context->kemAlgo->publicKeySize);
121  }
122 
123  //Successful memory allocation?
124  if(context->pk != NULL)
125  {
126  //Key pair generation
127  error = context->kemAlgo->generateKeyPair(prngAlgo, prngContext,
128  context->pk, context->sk);
129  }
130  else
131  {
132  //Failed to allocate memory
133  error = ERROR_OUT_OF_MEMORY;
134  }
135  }
136  else
137  {
138  //Failed to allocate memory
139  error = ERROR_OUT_OF_MEMORY;
140  }
141  }
142  else
143  {
144  //Invalid key encapsulation mechanism
145  error = ERROR_INVALID_PARAMETER;
146  }
147 
148  //Return status code
149  return error;
150 }
151 
152 
153 /**
154  * @brief Load public key
155  * @param[in] context Pointer to the KEM context
156  * @param[in] pk Public key
157  * @return Error code
158  **/
159 
160 error_t kemLoadPublicKey(KemContext *context, const uint8_t *pk)
161 {
162  error_t error;
163 
164  //Initialize status code
165  error = NO_ERROR;
166 
167  //Valid key encapsulation mechanism?
168  if(context->kemAlgo != NULL)
169  {
170  //Allocate a memory buffer to hold the public key
171  if(context->pk == NULL)
172  {
173  context->pk = cryptoAllocMem(context->kemAlgo->publicKeySize);
174  }
175 
176  //Successful memory allocation?
177  if(context->pk != NULL)
178  {
179  //Copy the public key
180  osMemcpy(context->pk, pk, context->kemAlgo->publicKeySize);
181  }
182  else
183  {
184  //Failed to allocate memory
185  error = ERROR_OUT_OF_MEMORY;
186  }
187  }
188  else
189  {
190  //Invalid key encapsulation mechanism
191  error = ERROR_INVALID_PARAMETER;
192  }
193 
194  //Return status code
195  return error;
196 }
197 
198 
199 /**
200  * @brief Encapsulation algorithm
201  * @param[in] context Pointer to the KEM context
202  * @param[in] prngAlgo PRNG algorithm
203  * @param[in] prngContext Pointer to the PRNG context
204  * @param[out] ct Ciphertext
205  * @param[out] ss Shared secret
206  * @return Error code
207  **/
208 
209 error_t kemEncapsulate(KemContext *context, const PrngAlgo *prngAlgo,
210  void *prngContext, uint8_t *ct, uint8_t *ss)
211 {
212  error_t error;
213 
214  //Valid parameters?
215  if(context->kemAlgo != NULL && context->pk != NULL)
216  {
217  //Encapsulation algorithm
218  error = context->kemAlgo->encapsulate(prngAlgo, prngContext, ct, ss,
219  context->pk);
220  }
221  else
222  {
223  //Invalid parameters
224  error = ERROR_INVALID_PARAMETER;
225  }
226 
227  //Return status code
228  return error;
229 }
230 
231 
232 /**
233  * @brief Decapsulation algorithm
234  * @param[in] context Pointer to the KEM context
235  * @param[in] ct Ciphertext
236  * @param[out] ss Shared secret
237  * @return Error code
238  **/
239 
240 error_t kemDecapsulate(KemContext *context, const uint8_t *ct, uint8_t *ss)
241 {
242  error_t error;
243 
244  //Valid parameters?
245  if(context->kemAlgo != NULL && context->sk != NULL)
246  {
247  //Decapsulation algorithm
248  error = context->kemAlgo->decapsulate(ss, ct, context->sk);
249  }
250  else
251  {
252  //Invalid key encapsulation mechanism
253  error = ERROR_INVALID_PARAMETER;
254  }
255 
256  //Return status code
257  return error;
258 }
259 
260 #endif
uint8_t * sk
Secret key.
Definition: kem.h:70
uint8_t * pk
Public key.
Definition: kem.h:71
#define PrngAlgo
Definition: crypto.h:938
void kemInit(KemContext *context, const KemAlgo *kemAlgo)
Initialize KEM context.
Definition: kem.c:48
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
size_t publicKeySize
Definition: crypto.h:1089
void kemFree(KemContext *context)
Release KEM context.
Definition: kem.c:62
error_t kemEncapsulate(KemContext *context, const PrngAlgo *prngAlgo, void *prngContext, uint8_t *ct, uint8_t *ss)
Encapsulation algorithm.
Definition: kem.c:209
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
KEM context.
Definition: kem.h:68
KemAlgoDecapsulate decapsulate
Definition: crypto.h:1095
General definitions for cryptographic algorithms.
size_t secretKeySize
Definition: crypto.h:1090
KemAlgoGenerateKeyPair generateKeyPair
Definition: crypto.h:1093
KemAlgoEncapsulate encapsulate
Definition: crypto.h:1094
error_t kemGenerateKeyPair(KemContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Key pair generation.
Definition: kem.c:100
#define cryptoFreeMem(p)
Definition: crypto.h:791
Common interface for key encapsulation mechanisms (KEM)
Definition: crypto.h:1087
error_t kemLoadPublicKey(KemContext *context, const uint8_t *pk)
Load public key.
Definition: kem.c:160
Key encapsulation mechanism (KEM)
error_t kemDecapsulate(KemContext *context, const uint8_t *ct, uint8_t *ss)
Decapsulation algorithm.
Definition: kem.c:240
const KemAlgo * kemAlgo
Key encapsulation mechanism.
Definition: kem.h:69
#define cryptoAllocMem(size)
Definition: crypto.h:786
#define osMemset(p, value, length)
Definition: os_port.h:135
@ NO_ERROR
Success.
Definition: error.h:44