1 /**
2  * \brief AES block cipher, ESP block hardware accelerated version
3  * Based on mbedTLS FIPS-197 compliant version.
4  *
5  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
6  *  Additions Copyright (C) 2016-2017, Espressif Systems (Shanghai) PTE Ltd
7  *  SPDX-License-Identifier: Apache-2.0
8  *
9  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
10  *  not use this file except in compliance with the License.
11  *  You may obtain a copy of the License at
12  *
13  *  http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *  Unless required by applicable law or agreed to in writing, software
16  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *  See the License for the specific language governing permissions and
19  *  limitations under the License.
20  *
21  */
22 /*
23  *  The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
24  *
25  *  http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
26  *  http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
27  */
28 #include <string.h>
29 #include "mbedtls/aes.h"
30 #include "mbedtls/platform_util.h"
31 #include "aes/esp_aes.h"
32 #include "soc/hwcrypto_periph.h"
33 #include <sys/lock.h>
34 #include "hal/aes_hal.h"
35 #include "aes/esp_aes_internal.h"
36 
37 #include <freertos/FreeRTOS.h>
38 
39 #include "soc/cpu.h"
40 #include <stdio.h>
41 #include "driver/periph_ctrl.h"
42 
43 
44 /* AES uses a spinlock mux not a lock as the underlying block operation
45    only takes 208 cycles (to write key & compute block), +600 cycles
46    for DPORT protection but +3400 cycles again if you use a full sized lock.
47 
48    For CBC, CFB, etc. this may mean that interrupts are disabled for a longer
49    period of time for bigger lengths. However at the moment this has to happen
50    anyway due to DPORT protection...
51 */
52 static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED;
53 
54 
esp_aes_acquire_hardware(void)55 void esp_aes_acquire_hardware( void )
56 {
57     portENTER_CRITICAL(&aes_spinlock);
58 
59     /* Enable AES hardware */
60     periph_module_enable(PERIPH_AES_MODULE);
61 }
62 
esp_aes_release_hardware(void)63 void esp_aes_release_hardware( void )
64 {
65     /* Disable AES hardware */
66     periph_module_disable(PERIPH_AES_MODULE);
67 
68     portEXIT_CRITICAL(&aes_spinlock);
69 }
70 
71 
72 
73 /* Run a single 16 byte block of AES, using the hardware engine.
74  *
75  * Call only while holding esp_aes_acquire_hardware().
76  */
esp_aes_block(esp_aes_context * ctx,const void * input,void * output)77 static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
78 {
79     uint32_t i0, i1, i2, i3;
80     const uint32_t *input_words = (uint32_t *)input;
81     uint32_t *output_words = (uint32_t *)output;
82 
83     /* If no key is written to hardware yet, either the user hasn't called
84        mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
85        know which mode to use - or a fault skipped the
86        key write to hardware. Treat this as a fatal error and zero the output block.
87     */
88     if (ctx->key_in_hardware != ctx->key_bytes) {
89         bzero(output, 16);
90         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
91     }
92     i0 = input_words[0];
93     i1 = input_words[1];
94     i2 = input_words[2];
95     i3 = input_words[3];
96 
97     aes_hal_transform_block(input, output);
98 
99     /* Physical security check: Verify the AES accelerator actually ran, and wasn't
100        skipped due to external fault injection while starting the peripheral.
101 
102        Note that i0,i1,i2,i3 are copied from input buffer in case input==output.
103 
104        Bypassing this check requires at least one additional fault.
105     */
106     if (i0 == output_words[0] && i1 == output_words[1] && i2 == output_words[2] && i3 == output_words[3]) {
107         // calling zeroing functions to narrow the
108         // window for a double-fault of the abort step, here
109         memset(output, 0, 16);
110         mbedtls_platform_zeroize(output, 16);
111         abort();
112     }
113 
114     return 0;
115 }
116 
esp_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])117 void esp_aes_encrypt(esp_aes_context *ctx,
118                      const unsigned char input[16],
119                      unsigned char output[16] )
120 {
121     esp_internal_aes_encrypt(ctx, input, output);
122 }
123 
124 /*
125  * AES-ECB block encryption
126  */
esp_internal_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])127 int esp_internal_aes_encrypt(esp_aes_context *ctx,
128                              const unsigned char input[16],
129                              unsigned char output[16] )
130 {
131     int r;
132 
133     if (!valid_key_length(ctx)) {
134         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
135     }
136 
137     esp_aes_acquire_hardware();
138     ctx->key_in_hardware = 0;
139     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
140     r = esp_aes_block(ctx, input, output);
141     esp_aes_release_hardware();
142     return r;
143 }
144 
esp_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])145 void esp_aes_decrypt(esp_aes_context *ctx,
146                      const unsigned char input[16],
147                      unsigned char output[16] )
148 {
149     esp_internal_aes_decrypt(ctx, input, output);
150 }
151 
152 /*
153  * AES-ECB block decryption
154  */
155 
esp_internal_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])156 int esp_internal_aes_decrypt(esp_aes_context *ctx,
157                              const unsigned char input[16],
158                              unsigned char output[16] )
159 {
160     int r;
161 
162     if (!valid_key_length(ctx)) {
163         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
164     }
165 
166     esp_aes_acquire_hardware();
167     ctx->key_in_hardware = 0;
168     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_DECRYPT);
169     r = esp_aes_block(ctx, input, output);
170     esp_aes_release_hardware();
171     return r;
172 }
173 
174 /*
175  * AES-ECB block encryption/decryption
176  */
esp_aes_crypt_ecb(esp_aes_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])177 int esp_aes_crypt_ecb(esp_aes_context *ctx,
178                       int mode,
179                       const unsigned char input[16],
180                       unsigned char output[16] )
181 {
182     int r;
183 
184     if (!valid_key_length(ctx)) {
185         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
186     }
187 
188     esp_aes_acquire_hardware();
189     ctx->key_in_hardware = 0;
190     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
191     r = esp_aes_block(ctx, input, output);
192     esp_aes_release_hardware();
193 
194     return r;
195 }
196 
197 
198 /*
199  * AES-CBC buffer encryption/decryption
200  */
esp_aes_crypt_cbc(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)201 int esp_aes_crypt_cbc(esp_aes_context *ctx,
202                       int mode,
203                       size_t length,
204                       unsigned char iv[16],
205                       const unsigned char *input,
206                       unsigned char *output )
207 {
208     uint32_t *output_words = (uint32_t *)output;
209     const uint32_t *input_words = (const uint32_t *)input;
210     uint32_t *iv_words = (uint32_t *)iv;
211     unsigned char temp[16];
212 
213     if ( length % 16 ) {
214         return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
215     }
216 
217     if (!valid_key_length(ctx)) {
218         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
219     }
220 
221     esp_aes_acquire_hardware();
222     ctx->key_in_hardware = 0;
223     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
224 
225 
226     if ( mode == ESP_AES_DECRYPT ) {
227         while ( length > 0 ) {
228             memcpy(temp, input_words, 16);
229             esp_aes_block(ctx, input_words, output_words);
230 
231             output_words[0] = output_words[0] ^ iv_words[0];
232             output_words[1] = output_words[1] ^ iv_words[1];
233             output_words[2] = output_words[2] ^ iv_words[2];
234             output_words[3] = output_words[3] ^ iv_words[3];
235 
236             memcpy( iv_words, temp, 16 );
237 
238             input_words += 4;
239             output_words += 4;
240             length -= 16;
241         }
242     } else { // ESP_AES_ENCRYPT
243         while ( length > 0 ) {
244 
245             output_words[0] = input_words[0] ^ iv_words[0];
246             output_words[1] = input_words[1] ^ iv_words[1];
247             output_words[2] = input_words[2] ^ iv_words[2];
248             output_words[3] = input_words[3] ^ iv_words[3];
249 
250             esp_aes_block(ctx, output_words, output_words);
251             memcpy( iv_words, output_words, 16 );
252 
253             input_words  += 4;
254             output_words += 4;
255             length -= 16;
256         }
257     }
258 
259     esp_aes_release_hardware();
260 
261     return 0;
262 }
263 
264 /*
265  * AES-CFB128 buffer encryption/decryption
266  */
esp_aes_crypt_cfb128(esp_aes_context * ctx,int mode,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)267 int esp_aes_crypt_cfb128(esp_aes_context *ctx,
268                          int mode,
269                          size_t length,
270                          size_t *iv_off,
271                          unsigned char iv[16],
272                          const unsigned char *input,
273                          unsigned char *output )
274 {
275     int c;
276     size_t n = *iv_off;
277 
278     if (!valid_key_length(ctx)) {
279         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
280     }
281 
282     esp_aes_acquire_hardware();
283     ctx->key_in_hardware = 0;
284     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
285 
286     if ( mode == ESP_AES_DECRYPT ) {
287         while ( length-- ) {
288             if ( n == 0 ) {
289                 esp_aes_block(ctx, iv, iv);
290             }
291 
292             c = *input++;
293             *output++ = (unsigned char)( c ^ iv[n] );
294             iv[n] = (unsigned char) c;
295 
296             n = ( n + 1 ) & 0x0F;
297         }
298     } else {
299         while ( length-- ) {
300             if ( n == 0 ) {
301                 esp_aes_block(ctx, iv, iv);
302             }
303 
304             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
305 
306             n = ( n + 1 ) & 0x0F;
307         }
308     }
309 
310     *iv_off = n;
311 
312     esp_aes_release_hardware();
313 
314     return 0;
315 }
316 
317 /*
318  * AES-CFB8 buffer encryption/decryption
319  */
esp_aes_crypt_cfb8(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)320 int esp_aes_crypt_cfb8(esp_aes_context *ctx,
321                        int mode,
322                        size_t length,
323                        unsigned char iv[16],
324                        const unsigned char *input,
325                        unsigned char *output )
326 {
327     unsigned char c;
328     unsigned char ov[17];
329 
330     if (!valid_key_length(ctx)) {
331         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
332     }
333 
334     esp_aes_acquire_hardware();
335     ctx->key_in_hardware = 0;
336     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
337 
338 
339     while ( length-- ) {
340         memcpy( ov, iv, 16 );
341         esp_aes_block(ctx, iv, iv);
342 
343         if ( mode == ESP_AES_DECRYPT ) {
344             ov[16] = *input;
345         }
346 
347         c = *output++ = (unsigned char)( iv[0] ^ *input++ );
348 
349         if ( mode == ESP_AES_ENCRYPT ) {
350             ov[16] = c;
351         }
352 
353         memcpy( iv, ov + 1, 16 );
354     }
355 
356     esp_aes_release_hardware();
357 
358     return 0;
359 }
360 
361 /*
362  * AES-CTR buffer encryption/decryption
363  */
esp_aes_crypt_ctr(esp_aes_context * ctx,size_t length,size_t * nc_off,unsigned char nonce_counter[16],unsigned char stream_block[16],const unsigned char * input,unsigned char * output)364 int esp_aes_crypt_ctr(esp_aes_context *ctx,
365                       size_t length,
366                       size_t *nc_off,
367                       unsigned char nonce_counter[16],
368                       unsigned char stream_block[16],
369                       const unsigned char *input,
370                       unsigned char *output )
371 {
372     int c, i;
373     size_t n = *nc_off;
374 
375     if (!valid_key_length(ctx)) {
376         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
377     }
378 
379     esp_aes_acquire_hardware();
380     ctx->key_in_hardware = 0;
381     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
382 
383 
384     while ( length-- ) {
385         if ( n == 0 ) {
386             esp_aes_block(ctx, nonce_counter, stream_block);
387 
388             for ( i = 16; i > 0; i-- ) {
389                 if ( ++nonce_counter[i - 1] != 0 ) {
390                     break;
391                 }
392             }
393         }
394         c = *input++;
395         *output++ = (unsigned char)( c ^ stream_block[n] );
396 
397         n = ( n + 1 ) & 0x0F;
398     }
399 
400     *nc_off = n;
401 
402     esp_aes_release_hardware();
403 
404     return 0;
405 }
406 
407 /*
408  * AES-OFB (Output Feedback Mode) buffer encryption/decryption
409  */
esp_aes_crypt_ofb(esp_aes_context * ctx,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)410 int esp_aes_crypt_ofb(esp_aes_context *ctx,
411                       size_t length,
412                       size_t *iv_off,
413                       unsigned char iv[16],
414                       const unsigned char *input,
415                       unsigned char *output )
416 {
417     int ret = 0;
418     size_t n;
419 
420     if (ctx == NULL || iv_off == NULL || iv == NULL ||
421             input == NULL || output == NULL ) {
422         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
423     }
424 
425     n = *iv_off;
426 
427     if (n > 15) {
428         return (MBEDTLS_ERR_AES_BAD_INPUT_DATA);
429     }
430 
431     if (!valid_key_length(ctx)) {
432         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
433     }
434 
435     esp_aes_acquire_hardware();
436     ctx->key_in_hardware = 0;
437     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
438 
439 
440     while (length--) {
441         if ( n == 0 ) {
442             esp_aes_block(ctx, iv, iv);
443         }
444         *output++ =  *input++ ^ iv[n];
445 
446         n = ( n + 1 ) & 0x0F;
447     }
448 
449     *iv_off = n;
450 
451     esp_aes_release_hardware();
452 
453     return ( ret );
454 }
455