Skip to content

Commit 86915d9

Browse files
authored
Merge pull request #8704 from RonEld/cryptocell_ccm_alt_fixes
Fix issues in Cryptocell 310 ccm_alt discovered by On Target Testing
2 parents 5e6dc94 + 5e0223f commit 86915d9

File tree

2 files changed

+114
-131
lines changed

2 files changed

+114
-131
lines changed

features/cryptocell/FEATURE_CRYPTOCELL310/ccm_alt.c

Lines changed: 112 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,9 @@
2222
#if defined(MBEDTLS_CCM_ALT)
2323
#include <string.h>
2424
#include "mbedtls/platform.h"
25+
#include "mbedtls/platform_util.h"
2526
#include "mbedtls/aes.h"
26-
27-
/* Implementation that should never be optimized out by the compiler */
28-
static void mbedtls_zeroize( void *v, size_t n ) {
29-
volatile unsigned char *p = (unsigned char*)v;
30-
while( n-- ) *p++ = 0;
31-
}
27+
#include "crys_aesccm_error.h"
3228

3329
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
3430
{
@@ -37,7 +33,7 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
3733

3834
void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
3935
{
40-
mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
36+
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
4137
}
4238

4339
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
@@ -46,18 +42,30 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
4642
unsigned int keybits )
4743
{
4844
if( ctx == NULL )
49-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
45+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
46+
47+
if( cipher != MBEDTLS_CIPHER_ID_AES )
48+
{
49+
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
50+
}
5051

51-
if( cipher != MBEDTLS_CIPHER_ID_AES ||
52-
keybits != 128 )
52+
switch( keybits )
5353
{
54-
return ( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
54+
case 128:
55+
{
56+
memcpy( ctx->cipher_key , key, keybits / 8 );
57+
ctx->key_size = CRYS_AES_Key128BitSize;
58+
}
59+
break;
60+
case 192:
61+
case 256:
62+
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
63+
default:
64+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
5565
}
5666

57-
memcpy( ctx->cipher_key , key, keybits / 8 );
58-
ctx->keySize_ID = CRYS_AES_Key128BitSize;
5967

60-
return ( 0 );
68+
return( 0 );
6169

6270
}
6371

@@ -66,36 +74,55 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
6674
*/
6775

6876
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
69-
const unsigned char *iv, size_t iv_len,
70-
const unsigned char *add, size_t add_len,
71-
const unsigned char *input, unsigned char *output,
72-
unsigned char *tag, size_t tag_len )
77+
const unsigned char *iv, size_t iv_len,
78+
const unsigned char *add, size_t add_len,
79+
const unsigned char *input,
80+
unsigned char *output,
81+
unsigned char *tag, size_t tag_len )
7382

7483
{
75-
CRYSError_t CrysRet = CRYS_OK;
84+
CRYSError_t crys_ret = CRYS_OK;
85+
CRYS_AESCCM_Mac_Res_t cc_mac_res = { 0 };
86+
int ret = 0;
7687
/*
7788
* Check length requirements: SP800-38C A.1
7889
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
7990
* 'length' checked later (when writing it to the first block)
8091
*/
8192
if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
82-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
93+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
94+
95+
if( tag_len > sizeof( cc_mac_res ) )
96+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
8397

8498
/* Also implies q is within bounds */
8599
if( iv_len < 7 || iv_len > 13 )
86-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
100+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
87101

88102
#if SIZE_MAX > UINT_MAX
89103
if( length > 0xFFFFFFFF || add_len > 0xFFFFFFFF )
90-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
104+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
91105
#endif
92106

93-
CrysRet = CRYS_AESCCM( SASI_AES_ENCRYPT, ctx->cipher_key, ctx->keySize_ID,(uint8_t*)iv, iv_len,
94-
(uint8_t*)add, add_len, (uint8_t*)input, length, output, tag_len, tag );
95-
if( CrysRet != CRYS_OK )
96-
return ( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
107+
crys_ret = CRYS_AESCCM( SASI_AES_ENCRYPT, ctx->cipher_key, ctx->key_size,
108+
(uint8_t*)iv, iv_len, (uint8_t*)add, add_len,
109+
(uint8_t*)input, length, output, tag_len,
110+
cc_mac_res );
111+
if( crys_ret == CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR )
112+
{
113+
ret = MBEDTLS_ERR_CCM_BAD_INPUT;
114+
goto exit;
115+
}
116+
else if( crys_ret != CRYS_OK )
117+
{
118+
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
119+
goto exit;
120+
}
121+
122+
memcpy( tag, cc_mac_res, tag_len );
97123

98-
return ( 0 );
124+
exit:
125+
return( ret );
99126

100127
}
101128

@@ -109,31 +136,80 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
109136
const unsigned char *tag, size_t tag_len )
110137

111138
{
112-
CRYSError_t CrysRet = CRYS_OK;
139+
CRYSError_t crys_ret = CRYS_OK;
140+
int ret = 0;
113141
/*
114142
* Check length requirements: SP800-38C A.1
115143
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
116144
* 'length' checked later (when writing it to the first block)
117145
*/
118146
if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
119-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
147+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
120148

121149
/* Also implies q is within bounds */
122150
if( iv_len < 7 || iv_len > 13 )
123-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
151+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
124152

125153
#if SIZE_MAX > UINT_MAX
126154
if( length > 0xFFFFFFFF || add_len > 0xFFFFFFFF )
127-
return ( MBEDTLS_ERR_CCM_BAD_INPUT );
155+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
128156
#endif
129157

130-
CrysRet = CRYS_AESCCM( SASI_AES_DECRYPT, ctx->cipher_key, ctx->keySize_ID,(uint8_t*)iv, iv_len,
131-
(uint8_t*)add, add_len, (uint8_t*)input, length, output, tag_len, (uint8_t*)tag );
132-
if ( CrysRet != CRYS_OK )
133-
return ( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
158+
crys_ret = CRYS_AESCCM( SASI_AES_DECRYPT, ctx->cipher_key, ctx->key_size,
159+
(uint8_t*)iv, iv_len, (uint8_t*)add, add_len,
160+
(uint8_t*)input, length, output, tag_len,
161+
(uint8_t*)tag );
162+
if( crys_ret == CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR )
163+
{
164+
/*
165+
* When CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR is returned,
166+
* no operation has occured, and no need to zeroize output.
167+
* In addition, it could be that the message length is too big,
168+
* returning this error code, and we don't want to overflow
169+
* the output buffer.
170+
*/
171+
return( MBEDTLS_ERR_CCM_BAD_INPUT );
172+
}
173+
else if( crys_ret == CRYS_FATAL_ERROR )
174+
{
175+
/*
176+
* Unfortunately, Crys AESCCM returns CRYS_FATAL_ERROR when
177+
* MAC isn't as expected.
178+
*/
179+
ret = MBEDTLS_ERR_CCM_AUTH_FAILED;
180+
goto exit;
181+
}
182+
else if( crys_ret != CRYS_OK )
183+
{
184+
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
185+
goto exit;
186+
}
134187

135-
return ( 0 );
188+
exit:
189+
if( ret != 0 )
190+
mbedtls_platform_zeroize( output, length );
191+
return( ret );
136192

137193
}
138194

195+
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
196+
const unsigned char *iv, size_t iv_len,
197+
const unsigned char *add, size_t add_len,
198+
const unsigned char *input,
199+
unsigned char *output,
200+
unsigned char *tag, size_t tag_len )
201+
{
202+
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
203+
}
204+
205+
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
206+
const unsigned char *iv, size_t iv_len,
207+
const unsigned char *add, size_t add_len,
208+
const unsigned char *input,
209+
unsigned char *output,
210+
const unsigned char *tag, size_t tag_len )
211+
{
212+
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
213+
}
214+
139215
#endif

features/cryptocell/FEATURE_CRYPTOCELL310/ccm_alt.h

Lines changed: 2 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -24,104 +24,11 @@
2424
#if defined(MBEDTLS_CCM_ALT)
2525
#include "crys_aesccm.h"
2626

27-
#ifdef __cplusplus
28-
extern "C" {
29-
#endif
30-
3127
typedef struct {
32-
CRYS_AESCCM_Key_t cipher_key; /*!< cipher key used */
33-
CRYS_AESCCM_KeySize_t keySize_ID;
28+
CRYS_AESCCM_Key_t cipher_key; /*!< cipher key used */
29+
CRYS_AESCCM_KeySize_t key_size;
3430
}
3531
mbedtls_ccm_context;
3632

37-
/**
38-
* \brief Initialize CCM context (just makes references valid)
39-
* Makes the context ready for mbedtls_ccm_setkey() or
40-
* mbedtls_ccm_free().
41-
*
42-
* \param ctx CCM context to initialize
43-
*/
44-
void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
45-
46-
/**
47-
* \brief CCM initialization (encryption and decryption)
48-
*
49-
* \param ctx CCM context to be initialized
50-
* \param cipher cipher to use (a 128-bit block cipher)
51-
* \param key encryption key
52-
* \param keybits key size in bits (must be acceptable by the cipher)
53-
*
54-
* \return 0 if successful, or a cipher specific error code
55-
*/
56-
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
57-
mbedtls_cipher_id_t cipher,
58-
const unsigned char *key,
59-
unsigned int keybits );
60-
61-
/**
62-
* \brief Free a CCM context and underlying cipher sub-context
63-
*
64-
* \param ctx CCM context to free
65-
*/
66-
void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
67-
68-
/**
69-
* \brief CCM buffer encryption
70-
*
71-
* \param ctx CCM context
72-
* \param length length of the input data in bytes
73-
* \param iv nonce (initialization vector)
74-
* \param iv_len length of IV in bytes
75-
* must be 2, 3, 4, 5, 6, 7 or 8
76-
* \param add additional data
77-
* \param add_len length of additional data in bytes
78-
* must be less than 2^16 - 2^8
79-
* \param input buffer holding the input data
80-
* \param output buffer for holding the output data
81-
* must be at least 'length' bytes wide
82-
* \param tag buffer for holding the tag
83-
* \param tag_len length of the tag to generate in bytes
84-
* must be 4, 6, 8, 10, 14 or 16
85-
*
86-
* \note The tag is written to a separate buffer. To get the tag
87-
* concatenated with the output as in the CCM spec, use
88-
* tag = output + length and make sure the output buffer is
89-
* at least length + tag_len wide.
90-
*
91-
* \return 0 if successful
92-
*/
93-
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
94-
const unsigned char *iv, size_t iv_len,
95-
const unsigned char *add, size_t add_len,
96-
const unsigned char *input, unsigned char *output,
97-
unsigned char *tag, size_t tag_len );
98-
99-
/**
100-
* \brief CCM buffer authenticated decryption
101-
*
102-
* \param ctx CCM context
103-
* \param length length of the input data
104-
* \param iv initialization vector
105-
* \param iv_len length of IV
106-
* \param add additional data
107-
* \param add_len length of additional data
108-
* \param input buffer holding the input data
109-
* \param output buffer for holding the output data
110-
* \param tag buffer holding the tag
111-
* \param tag_len length of the tag
112-
*
113-
* \return 0 if successful and authenticated,
114-
* MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match
115-
*/
116-
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
117-
const unsigned char *iv, size_t iv_len,
118-
const unsigned char *add, size_t add_len,
119-
const unsigned char *input, unsigned char *output,
120-
const unsigned char *tag, size_t tag_len );
121-
122-
#ifdef __cplusplus
123-
}
124-
#endif
125-
12633
#endif /* MBEDTLS_CCM_ALT */
12734
#endif /* __CCM_ALT__ */

0 commit comments

Comments
 (0)