saml11_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file saml11_crypto_cipher.c
3  * @brief SAML11 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 "sam.h"
36 #include "core/crypto.h"
40 #include "aead/aead_algorithms.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (SAML11_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  //192 and 256-bit keys are not supported
62  if(keyLen != 16)
64 
65  //10 rounds are required for 128-bit key
66  context->nr = 10;
67 
68  //Copy the original key
69  context->ek[0] = LOAD32LE(key);
70  context->ek[1] = LOAD32LE(key + 4);
71  context->ek[2] = LOAD32LE(key + 8);
72  context->ek[3] = LOAD32LE(key + 12);
73 
74  //No error to report
75  return NO_ERROR;
76 }
77 
78 
79 /**
80  * @brief Encrypt a 16-byte block using AES algorithm
81  * @param[in] context Pointer to the AES context
82  * @param[in] input Plaintext block to encrypt
83  * @param[out] output Ciphertext block resulting from encryption
84  **/
85 
86 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
87 {
88  uint32_t p[4];
89  uint32_t c[4];
90 
91  //The pointer to the plaintext must be 32-bit aligned
92  osMemcpy(p, input, sizeof(p));
93 
94  //Acquire exclusive access to the CRYA module
96  //Perform AES-128 encryption
97  crya_aes_encrypt((uint8_t *) context->ek, 4, (uint8_t *) p, (uint8_t *) c);
98  //Release exclusive access to the CRYA module
100 
101  //Copy the resulting ciphertext
102  osMemcpy(output, c, sizeof(c));
103 }
104 
105 
106 /**
107  * @brief Decrypt a 16-byte block using AES algorithm
108  * @param[in] context Pointer to the AES context
109  * @param[in] input Ciphertext block to decrypt
110  * @param[out] output Plaintext block resulting from decryption
111  **/
112 
113 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
114 {
115  uint32_t p[4];
116  uint32_t c[4];
117 
118  //The pointer to the ciphertext must be 32-bit aligned
119  osMemcpy(c, input, sizeof(c));
120 
121  //Acquire exclusive access to the CRYA module
123  //Perform AES-128 decryption
124  crya_aes_decrypt((uint8_t *) context->ek, 4, (uint8_t *) c, (uint8_t *) p);
125  //Release exclusive access to the CRYA module
127 
128  //Copy the resulting plaintext
129  osMemcpy(output, p, sizeof(p));
130 }
131 
132 
133 #if (GCM_SUPPORT == ENABLED)
134 
135 /**
136  * @brief Initialize GCM context
137  * @param[in] context Pointer to the GCM context
138  * @param[in] cipherAlgo Cipher algorithm
139  * @param[in] cipherContext Pointer to the cipher algorithm context
140  * @return Error code
141  **/
142 
143 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
144  void *cipherContext)
145 {
146  uint32_t h[4];
147 
148  //The CRYPTO module only supports AES cipher algorithm
149  if(cipherAlgo != AES_CIPHER_ALGO)
151 
152  //Save cipher algorithm context
153  context->cipherAlgo = cipherAlgo;
154  context->cipherContext = cipherContext;
155 
156  //Let H = 0
157  h[0] = 0;
158  h[1] = 0;
159  h[2] = 0;
160  h[3] = 0;
161 
162  //Generate the hash subkey H
163  aesEncryptBlock(context->cipherContext, (uint8_t *) h, (uint8_t *) h);
164 
165  //Save the resulting value
166  context->m[0][0] = h[0];
167  context->m[0][1] = h[1];
168  context->m[0][2] = h[2];
169  context->m[0][3] = h[3];
170 
171  //Successful initialization
172  return NO_ERROR;
173 }
174 
175 
176 /**
177  * @brief Multiplication operation in GF(2^128)
178  * @param[in] context Pointer to the GCM context
179  * @param[in, out] x 16-byte block to be multiplied by H
180  **/
181 
182 void gcmMul(GcmContext *context, uint8_t *x)
183 {
184  uint32_t a[4];
185  uint32_t r[4];
186 
187  //The pointer to the input block must be 32-bit aligned
188  osMemcpy(a, x, sizeof(a));
189 
190  //Acquire exclusive access to the CRYA module
192  //Perform GF(2^128) multiplication
193  crya_gf_mult128(a, context->m[0], r);
194  //Release exclusive access to the CRYA module
196 
197  //Copy the resulting block
198  osMemcpy(x, r, sizeof(r));
199 }
200 
201 #endif
202 #endif
#define AES_CIPHER_ALGO
Definition: aes.h:45
Collection of AEAD algorithms.
#define LOAD32LE(p)
Definition: cpu_endian.h:203
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.
#define crya_aes_encrypt
#define crya_gf_mult128
#define crya_aes_decrypt
OsMutex saml11CryptoMutex
Definition: saml11_crypto.c:41
SAML11 hardware cryptographic accelerator.
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.
SAML11 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