1818
1919#include <mbedtls/error_common.h>
2020#include "mbedtls/constant_time.h"
21+ #include "constant_time_internal.h"
2122#include <string.h>
2223
2324#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC )
@@ -154,11 +155,139 @@ static psa_status_t psa_hmac_finish_internal(
154155#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
155156
156157#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC )
157- static psa_status_t cmac_setup (mbedtls_psa_mac_operation_t * operation ,
158- const psa_key_attributes_t * attributes ,
159- const uint8_t * key_buffer )
158+ /*
159+ * Multiplication by u in the Galois field of GF(2^n)
160+ *
161+ * As explained in NIST SP 800-38B, this can be computed:
162+ *
163+ * If MSB(p) = 0, then p = (p << 1)
164+ * If MSB(p) = 1, then p = (p << 1) ^ R_n
165+ * with R_64 = 0x1B and R_128 = 0x87
166+ *
167+ * Input and output MUST NOT point to the same buffer
168+ * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
169+ */
170+ static int cmac_multiply_by_u (unsigned char * output ,
171+ const unsigned char * input ,
172+ size_t blocksize )
173+ {
174+ const unsigned char R_128 = 0x87 ;
175+ unsigned char R_n ;
176+ uint32_t overflow = 0x00 ;
177+ int i ;
178+
179+ if (blocksize == PSA_AES_BLOCK_SIZE ) {
180+ R_n = R_128 ;
181+ }
182+ #if defined(PSA_WANT_KEY_TYPE_DES )
183+ else if (blocksize == PSA_DES_BLOCK_SIZE ) {
184+ const unsigned char R_64 = 0x1B ;
185+ R_n = R_64 ;
186+ }
187+ #endif
188+ else {
189+ return PSA_ERROR_INVALID_ARGUMENT ;
190+ }
191+
192+ for (i = (int ) blocksize - 4 ; i >= 0 ; i -= 4 ) {
193+ uint32_t i32 = MBEDTLS_GET_UINT32_BE (& input [i ], 0 );
194+ uint32_t new_overflow = i32 >> 31 ;
195+ i32 = (i32 << 1 ) | overflow ;
196+ MBEDTLS_PUT_UINT32_BE (i32 , & output [i ], 0 );
197+ overflow = new_overflow ;
198+ }
199+
200+ R_n = (unsigned char ) mbedtls_ct_uint_if_else_0 (mbedtls_ct_bool (input [0 ] >> 7 ), R_n );
201+ output [blocksize - 1 ] ^= R_n ;
202+
203+ return 0 ;
204+ }
205+
206+ /*
207+ * Generate subkeys
208+ *
209+ * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
210+ */
211+ static int cmac_generate_subkeys (psa_cipher_operation_t * ctx , size_t block_size ,
212+ unsigned char * K1 , unsigned char * K2 )
213+ {
214+ int ret = PSA_ERROR_CORRUPTION_DETECTED ;
215+ unsigned char L [PSA_CMAC_MAX_BLOCK_SIZE ];
216+ size_t olen ;
217+
218+ mbedtls_platform_zeroize (L , sizeof (L ));
219+
220+ /* Calculate Ek(0) */
221+ if ((ret = psa_cipher_update (ctx , L , block_size , L , PSA_CMAC_MAX_BLOCK_SIZE , & olen )) != 0 ) {
222+ goto exit ;
223+ }
224+
225+ /*
226+ * Generate K1 and K2
227+ */
228+ if ((ret = cmac_multiply_by_u (K1 , L , block_size )) != 0 ) {
229+ goto exit ;
230+ }
231+
232+ if ((ret = cmac_multiply_by_u (K2 , K1 , block_size )) != 0 ) {
233+ goto exit ;
234+ }
235+
236+ exit :
237+ mbedtls_platform_zeroize (L , sizeof (L ));
238+
239+ return ret ;
240+ }
241+
242+ /*
243+ * Create padded last block from (partial) last block.
244+ *
245+ * We can't use the padding option from the cipher layer, as it only works for
246+ * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
247+ */
248+ static void cmac_pad (unsigned char padded_block [PSA_CMAC_MAX_BLOCK_SIZE ],
249+ size_t padded_block_len ,
250+ const unsigned char * last_block ,
251+ size_t last_block_len )
160252{
161- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED ;
253+ size_t j ;
254+
255+ for (j = 0 ; j < padded_block_len ; j ++ ) {
256+ if (j < last_block_len ) {
257+ padded_block [j ] = last_block [j ];
258+ } else if (j == last_block_len ) {
259+ padded_block [j ] = 0x80 ;
260+ } else {
261+ padded_block [j ] = 0x00 ;
262+ }
263+ }
264+ }
265+
266+ static psa_status_t psa_cmac_abort_internal (
267+ mbedtls_psa_cmac_operation_t * cmac )
268+ {
269+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED ;
270+
271+ status = psa_destroy_key (cmac -> key_id );
272+ if (status != PSA_SUCCESS ) {
273+ return status ;
274+ }
275+
276+ status = psa_cipher_abort (& cmac -> cipher_ctx );
277+ if (status != PSA_SUCCESS ) {
278+ return status ;
279+ }
280+
281+ mbedtls_platform_zeroize (cmac , sizeof (mbedtls_psa_cmac_operation_t ));
282+ return status ;
283+ }
284+
285+ static psa_status_t psa_cmac_setup_internal (mbedtls_psa_cmac_operation_t * cmac ,
286+ const psa_key_attributes_t * attributes ,
287+ const uint8_t * key_buffer ,
288+ size_t key_buffer_size )
289+ {
290+ int status = PSA_ERROR_CORRUPTION_DETECTED ;
162291
163292#if defined(PSA_WANT_KEY_TYPE_DES )
164293 /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
@@ -170,27 +299,167 @@ static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation,
170299 }
171300#endif
172301
173- const mbedtls_cipher_info_t * cipher_info =
174- mbedtls_cipher_info_from_psa (
175- PSA_ALG_CMAC ,
176- psa_get_key_type (attributes ),
177- psa_get_key_bits (attributes ),
178- NULL );
302+ psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT ;
303+ psa_key_type_t key_type = psa_get_key_type (attributes );
304+ size_t key_bits = psa_get_key_bits (attributes );
305+ psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING ;
179306
307+ /* Set up key attributes for PSA import */
308+ psa_set_key_type (& key_attributes , key_type );
309+ psa_set_key_bits (& key_attributes , key_bits );
310+ psa_set_key_usage_flags (& key_attributes , PSA_KEY_USAGE_ENCRYPT );
311+ psa_set_key_algorithm (& key_attributes , alg );
312+
313+ /* Import key for cipher operations */
314+ status = psa_import_key (& key_attributes , key_buffer , key_buffer_size , & cmac -> key_id );
315+ if (status != PSA_SUCCESS ) {
316+ return status ;
317+ }
318+
319+ status = psa_cipher_encrypt_setup (& cmac -> cipher_ctx , cmac -> key_id , alg );
320+ if (status != 0 ) {
321+ return status ;
322+ }
323+
324+ const mbedtls_cipher_info_t * cipher_info = mbedtls_cipher_info_from_psa (alg , key_type , key_bits , NULL );
180325 if (cipher_info == NULL ) {
181326 return PSA_ERROR_NOT_SUPPORTED ;
182327 }
183328
184- ret = mbedtls_cipher_setup (& operation -> ctx .cmac , cipher_info );
185- if (ret != 0 ) {
329+ /* Ensure we're using a supported block cipher */
330+ switch (cipher_info -> type ) {
331+ case MBEDTLS_CIPHER_AES_128_ECB :
332+ case MBEDTLS_CIPHER_AES_192_ECB :
333+ case MBEDTLS_CIPHER_AES_256_ECB :
334+ case MBEDTLS_CIPHER_DES_EDE3_ECB :
335+ break ;
336+ default :
337+ return PSA_ERROR_INVALID_ARGUMENT ;
338+ }
339+
340+ cmac -> unprocessed_len = 0 ;
341+ cmac -> cipher_block_length = mbedtls_cipher_info_get_block_size (cipher_info );
342+ mbedtls_platform_zeroize (cmac -> state , sizeof (cmac -> state ));
343+ mbedtls_platform_zeroize (cmac -> unprocessed_block , sizeof (cmac -> unprocessed_block ));
344+ return PSA_SUCCESS ;
345+ }
346+
347+ static psa_status_t psa_cmac_update_internal (
348+ mbedtls_psa_cmac_operation_t * cmac ,
349+ const uint8_t * data ,
350+ size_t data_length )
351+ {
352+ unsigned char * state = cmac -> state ;
353+ int ret = 0 ;
354+ size_t n , j , olen , block_size ;
355+
356+ if (cmac == NULL || data == NULL ) {
357+ return PSA_ERROR_INVALID_ARGUMENT ;
358+ }
359+
360+ block_size = cmac -> cipher_block_length ;
361+
362+ /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
363+ * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
364+ MBEDTLS_ASSUME (block_size <= PSA_CMAC_MAX_BLOCK_SIZE );
365+
366+ /* Is there data still to process from the last call, that's greater in
367+ * size than a block? */
368+ if (cmac -> unprocessed_len > 0 &&
369+ data_length > block_size - cmac -> unprocessed_len ) {
370+ memcpy (& cmac -> unprocessed_block [cmac -> unprocessed_len ],
371+ data ,
372+ block_size - cmac -> unprocessed_len );
373+
374+ mbedtls_xor_no_simd (state , cmac -> unprocessed_block , state , block_size );
375+
376+ if ((ret = psa_cipher_update (& cmac -> cipher_ctx , state , block_size , state , PSA_CMAC_MAX_BLOCK_SIZE , & olen )) != 0 ) {
377+ goto exit ;
378+ }
379+
380+ data += block_size - cmac -> unprocessed_len ;
381+ data_length -= block_size - cmac -> unprocessed_len ;
382+ cmac -> unprocessed_len = 0 ;
383+ }
384+
385+ /* n is the number of blocks including any final partial block */
386+ n = (data_length + block_size - 1 ) / block_size ;
387+
388+ /* Iterate across the input data in block sized chunks, excluding any
389+ * final partial or complete block */
390+ for (j = 1 ; j < n ; j ++ ) {
391+ mbedtls_xor_no_simd (state , data , state , block_size );
392+
393+ if ((ret = psa_cipher_update (& cmac -> cipher_ctx , state , block_size , state , PSA_CMAC_MAX_BLOCK_SIZE , & olen )) != 0 ) {
394+ goto exit ;
395+ }
396+
397+ data_length -= block_size ;
398+ data += block_size ;
399+ }
400+
401+ /* If there is data left over that wasn't aligned to a block */
402+ if (data_length > 0 ) {
403+ memcpy (& cmac -> unprocessed_block [cmac -> unprocessed_len ],
404+ data ,
405+ data_length );
406+ cmac -> unprocessed_len += data_length ;
407+ }
408+
409+ exit :
410+ return ret ;
411+ }
412+
413+ static psa_status_t psa_cmac_finish_internal (
414+ mbedtls_psa_cmac_operation_t * cmac ,
415+ uint8_t * mac , size_t mac_size )
416+ {
417+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED ;
418+ size_t olen , block_size ;
419+
420+ unsigned char * state , * last_block ;
421+ unsigned char K1 [PSA_CMAC_MAX_BLOCK_SIZE ];
422+ unsigned char K2 [PSA_CMAC_MAX_BLOCK_SIZE ];
423+ unsigned char M_last [PSA_CMAC_MAX_BLOCK_SIZE ];
424+
425+ if (cmac == NULL || mac == NULL ) {
426+ return PSA_ERROR_INVALID_ARGUMENT ;
427+ }
428+
429+ state = cmac -> state ;
430+ block_size = cmac -> cipher_block_length ;
431+
432+ mbedtls_platform_zeroize (K1 , sizeof (K1 ));
433+ mbedtls_platform_zeroize (K2 , sizeof (K2 ));
434+ cmac_generate_subkeys (& cmac -> cipher_ctx , block_size , K1 , K2 );
435+
436+ last_block = cmac -> unprocessed_block ;
437+
438+ /* Calculate last block */
439+ if (cmac -> unprocessed_len < block_size ) {
440+ cmac_pad (M_last , block_size , last_block , cmac -> unprocessed_len );
441+ mbedtls_xor (M_last , M_last , K2 , block_size );
442+ } else {
443+ /* Last block is complete block */
444+ mbedtls_xor (M_last , last_block , K1 , block_size );
445+ }
446+
447+ mbedtls_xor (state , M_last , state , block_size );
448+ if ((status = psa_cipher_update (& cmac -> cipher_ctx , state , block_size , state , PSA_CMAC_MAX_BLOCK_SIZE , & olen )) != 0 ) {
186449 goto exit ;
187450 }
188451
189- ret = mbedtls_cipher_cmac_starts (& operation -> ctx .cmac ,
190- key_buffer ,
191- psa_get_key_bits (attributes ));
452+ memcpy (mac , state , mac_size );
453+
192454exit :
193- return mbedtls_to_psa_error (ret );
455+ mbedtls_platform_zeroize (K1 , sizeof (K1 ));
456+ mbedtls_platform_zeroize (K2 , sizeof (K2 ));
457+
458+ cmac -> unprocessed_len = 0 ;
459+ mbedtls_platform_zeroize (cmac -> unprocessed_block , sizeof (cmac -> unprocessed_block ));
460+ mbedtls_platform_zeroize (state , PSA_CMAC_MAX_BLOCK_SIZE );
461+
462+ return status ;
194463}
195464#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
196465
@@ -209,7 +478,7 @@ static psa_status_t mac_init(
209478
210479#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC )
211480 if (PSA_ALG_FULL_LENGTH_MAC (operation -> alg ) == PSA_ALG_CMAC ) {
212- mbedtls_cipher_init (& operation -> ctx .cmac );
481+ memset (& operation -> ctx .cmac , 0 , sizeof ( operation -> ctx . cmac ) );
213482 status = PSA_SUCCESS ;
214483 } else
215484#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
@@ -241,7 +510,7 @@ psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation)
241510 } else
242511#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC )
243512 if (PSA_ALG_FULL_LENGTH_MAC (operation -> alg ) == PSA_ALG_CMAC ) {
244- mbedtls_cipher_free (& operation -> ctx .cmac );
513+ return psa_cmac_abort_internal (& operation -> ctx .cmac );
245514 } else
246515#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
247516#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC )
@@ -290,8 +559,7 @@ static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation,
290559 if (PSA_ALG_FULL_LENGTH_MAC (alg ) == PSA_ALG_CMAC ) {
291560 /* Key buffer size for CMAC is dictated by the key bits set on the
292561 * attributes, and previously validated by the core on key import. */
293- (void ) key_buffer_size ;
294- status = cmac_setup (operation , attributes , key_buffer );
562+ status = psa_cmac_setup_internal (& operation -> ctx .cmac , attributes , key_buffer , key_buffer_size );
295563 } else
296564#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
297565#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC )
@@ -349,9 +617,7 @@ psa_status_t mbedtls_psa_mac_update(
349617
350618#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC )
351619 if (PSA_ALG_FULL_LENGTH_MAC (operation -> alg ) == PSA_ALG_CMAC ) {
352- return mbedtls_to_psa_error (
353- mbedtls_cipher_cmac_update (& operation -> ctx .cmac ,
354- input , input_length ));
620+ return psa_cmac_update_internal (& operation -> ctx .cmac , input , input_length );
355621 } else
356622#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
357623#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC )
@@ -375,13 +641,7 @@ static psa_status_t psa_mac_finish_internal(
375641{
376642#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC )
377643 if (PSA_ALG_FULL_LENGTH_MAC (operation -> alg ) == PSA_ALG_CMAC ) {
378- uint8_t tmp [PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE ];
379- int ret = mbedtls_cipher_cmac_finish (& operation -> ctx .cmac , tmp );
380- if (ret == 0 ) {
381- memcpy (mac , tmp , mac_size );
382- }
383- mbedtls_platform_zeroize (tmp , sizeof (tmp ));
384- return mbedtls_to_psa_error (ret );
644+ return psa_cmac_finish_internal (& operation -> ctx .cmac , mac , mac_size );
385645 } else
386646#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
387647#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC )
0 commit comments