pic32cm_ls_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file pic32cm_ls_crypto_cipher.c
3  * @brief PIC32CM LS00/LS60 cipher hardware accelerator
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.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "pic32c.h"
36 #include "core/crypto.h"
40 #include "aead/aead_algorithms.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (PIC32CM_LS_CRYPTO_CIPHER_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Key expansion
49  * @param[in] context Pointer to the AES context to initialize
50  * @param[in] key Pointer to the key
51  * @param[in] keyLen Length of the key
52  * @return Error code
53  **/
54 
55 error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
56 {
57  //Check parameters
58  if(context == NULL || key == NULL)
60 
61  //Check the length of the key
62  if(keyLen == 16)
63  {
64  //10 rounds are required for 128-bit key
65  context->nr = 10;
66  }
67  else if(keyLen == 24)
68  {
69  //12 rounds are required for 192-bit key
70  context->nr = 12;
71  }
72  else if(keyLen == 32)
73  {
74  //14 rounds are required for 256-bit key
75  context->nr = 14;
76  }
77  else
78  {
79  //Report an error
81  }
82 
83  //Copy the original key
84  osMemcpy(context->ek, key, keyLen);
85 
86  //No error to report
87  return NO_ERROR;
88 }
89 
90 
91 /**
92  * @brief Encrypt a 16-byte block using AES algorithm
93  * @param[in] context Pointer to the AES context
94  * @param[in] input Plaintext block to encrypt
95  * @param[out] output Ciphertext block resulting from encryption
96  **/
97 
98 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
99 {
100  size_t keySize;
101  uint32_t p[4];
102  uint32_t c[4];
103 
104  //Check the length of the key
105  if(context->nr == 10)
106  {
107  //10 rounds are required for 128-bit key
108  keySize = 4;
109  }
110  else if(context->nr == 12)
111  {
112  //12 rounds are required for 192-bit key
113  keySize = 6;
114  }
115  else
116  {
117  //14 rounds are required for 256-bit key
118  keySize = 8;
119  }
120 
121  //The pointer to the plaintext must be 32-bit aligned
122  osMemcpy(p, input, sizeof(p));
123 
124  //Acquire exclusive access to the CRYA module
126 
127  //Perform AES-128 encryption
128  crya_aes_encrypt((uint8_t *) context->ek, keySize, (uint8_t *) p,
129  (uint8_t *) c);
130 
131  //Release exclusive access to the CRYA module
133 
134  //Copy the resulting ciphertext
135  osMemcpy(output, c, sizeof(c));
136 }
137 
138 
139 /**
140  * @brief Decrypt a 16-byte block using AES algorithm
141  * @param[in] context Pointer to the AES context
142  * @param[in] input Ciphertext block to decrypt
143  * @param[out] output Plaintext block resulting from decryption
144  **/
145 
146 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
147 {
148  size_t keySize;
149  uint32_t p[4];
150  uint32_t c[4];
151 
152  //Check the length of the key
153  if(context->nr == 10)
154  {
155  //10 rounds are required for 128-bit key
156  keySize = 4;
157  }
158  else if(context->nr == 12)
159  {
160  //12 rounds are required for 192-bit key
161  keySize = 6;
162  }
163  else
164  {
165  //14 rounds are required for 256-bit key
166  keySize = 8;
167  }
168 
169  //The pointer to the ciphertext must be 32-bit aligned
170  osMemcpy(c, input, sizeof(c));
171 
172  //Acquire exclusive access to the CRYA module
174 
175  //Perform AES-128 decryption
176  crya_aes_decrypt((uint8_t *) context->ek, keySize, (uint8_t *) c,
177  (uint8_t *) p);
178 
179  //Release exclusive access to the CRYA module
181 
182  //Copy the resulting plaintext
183  osMemcpy(output, p, sizeof(p));
184 }
185 
186 
187 #if (GCM_SUPPORT == ENABLED)
188 
189 /**
190  * @brief Initialize GCM context
191  * @param[in] context Pointer to the GCM context
192  * @param[in] cipherAlgo Cipher algorithm
193  * @param[in] cipherContext Pointer to the cipher algorithm context
194  * @return Error code
195  **/
196 
197 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
198  void *cipherContext)
199 {
200  uint32_t h[4];
201 
202  //The CRYPTO module only supports AES cipher algorithm
203  if(cipherAlgo != AES_CIPHER_ALGO)
205 
206  //Save cipher algorithm context
207  context->cipherAlgo = cipherAlgo;
208  context->cipherContext = cipherContext;
209 
210  //Let H = 0
211  h[0] = 0;
212  h[1] = 0;
213  h[2] = 0;
214  h[3] = 0;
215 
216  //Generate the hash subkey H
217  aesEncryptBlock(context->cipherContext, (uint8_t *) h, (uint8_t *) h);
218 
219  //Save the resulting value
220  context->m[0][0] = h[0];
221  context->m[0][1] = h[1];
222  context->m[0][2] = h[2];
223  context->m[0][3] = h[3];
224 
225  //Successful initialization
226  return NO_ERROR;
227 }
228 
229 
230 /**
231  * @brief Multiplication operation in GF(2^128)
232  * @param[in] context Pointer to the GCM context
233  * @param[in, out] x 16-byte block to be multiplied by H
234  **/
235 
236 void gcmMul(GcmContext *context, uint8_t *x)
237 {
238  uint32_t a[4];
239  uint32_t r[4];
240 
241  //The pointer to the input block must be 32-bit aligned
242  osMemcpy(a, x, sizeof(a));
243 
244  //Acquire exclusive access to the CRYA module
246  //Perform GF(2^128) multiplication
247  crya_gf_mult128(a, context->m[0], r);
248  //Release exclusive access to the CRYA module
250 
251  //Copy the resulting block
252  osMemcpy(x, r, sizeof(r));
253 }
254 
255 #endif
256 #endif
#define AES_CIPHER_ALGO
Definition: aes.h:45
Collection of AEAD algorithms.
General definitions for cryptographic algorithms.
Debugging facilities.
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t x
Definition: lldp_ext_med.h:211
uint8_t h
Definition: ndp.h:302
uint8_t c
Definition: ndp.h:514
uint8_t r
Definition: ndp.h:346
uint8_t p
Definition: ndp.h:300
uint8_t a
Definition: ndp.h:411
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
OsMutex pic32cmlsCryptoMutex
PIC32CM LS00/LS60 hardware cryptographic accelerator.
#define crya_aes_encrypt
#define crya_gf_mult128
#define crya_aes_decrypt
error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
void gcmMul(GcmContext *context, uint8_t *x)
Multiplication operation in GF(2^128)
void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using AES algorithm.
void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using AES algorithm.
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
PIC32CM LS00/LS60 cipher hardware accelerator.
AES algorithm context.
Definition: aes.h:58
uint_t nr
Definition: aes.h:59
uint32_t ek[60]
Definition: aes.h:60
Common interface for encryption algorithms.
Definition: crypto.h:1036
GCM context.
Definition: gcm.h:64
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: gcm.h:65
void * cipherContext
Cipher algorithm context.
Definition: gcm.h:66
uint32_t m[GCM_TABLE_N][4]
Precalculated table.
Definition: gcm.h:67