Skip to content

Commit 84aec00

Browse files
authored
Merge pull request #776 from libtom/pr/ccm-nonce
Fix issue #775 - CCM nonce is 7..13 bytes
2 parents 1027dcf + e00b22d commit 84aec00

4 files changed

Lines changed: 60 additions & 8 deletions

File tree

‎demos/timing.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ static void time_ccm(eac_ctx *ctx)
13541354
t_start();
13551355
t1 = t_read();
13561356
z = 16;
1357-
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, NULL, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
1357+
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, NULL, ctx->IV, 13, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
13581358
fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
13591359
exit(EXIT_FAILURE);
13601360
}
@@ -1369,7 +1369,7 @@ static void time_ccm(eac_ctx *ctx)
13691369
t_start();
13701370
t1 = t_read();
13711371
z = 16;
1372-
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, &skey, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
1372+
if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, &skey, ctx->IV, 13, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
13731373
fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
13741374
exit(EXIT_FAILURE);
13751375
}

‎src/encauth/ccm/ccm_add_nonce.c‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,21 @@ int ccm_add_nonce(ccm_state *ccm,
2020
LTC_ARGCHK(ccm != NULL);
2121
LTC_ARGCHK(nonce != NULL);
2222

23-
/* increase L to match the nonce len */
24-
ccm->noncelen = (noncelen > 13) ? 13 : noncelen;
23+
/* CCM nonce is 7..13 bytes */
24+
if (noncelen < 7 || noncelen > 13) {
25+
return CRYPT_INVALID_ARG;
26+
}
27+
ccm->noncelen = noncelen;
2528
if ((15 - ccm->noncelen) > ccm->L) {
2629
ccm->L = 15 - ccm->noncelen;
2730
}
2831
if (ccm->L > 8) {
2932
return CRYPT_INVALID_ARG;
3033
}
3134

32-
/* decrease noncelen to match L */
35+
/* flags byte + nonce + length field must fit the 16-byte block */
3336
if ((ccm->noncelen + ccm->L) > 15) {
34-
ccm->noncelen = 15 - ccm->L;
37+
return CRYPT_INVALID_ARG;
3538
}
3639

3740
/* form B_0 == flags | Nonce N | l(m) */

‎src/encauth/ccm/ccm_memory.c‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ int ccm_memory(int cipher,
7878
if (*taglen < 4 || *taglen > 16 || (*taglen % 2) == 1 || headerlen > 0x7fffffffu) {
7979
return CRYPT_INVALID_ARG;
8080
}
81-
if (noncelen < 7) {
81+
/* CCM nonce is 7..13 bytes */
82+
if (noncelen < 7 || noncelen > 13) {
8283
return CRYPT_INVALID_ARG;
8384
}
8485

@@ -107,14 +108,18 @@ int ccm_memory(int cipher,
107108
}
108109

109110
/* increase L to match the nonce len */
110-
noncelen = (noncelen > 13) ? 13 : noncelen;
111111
if ((15 - noncelen) > L) {
112112
L = 15 - noncelen;
113113
}
114114
if (L > 8) {
115115
return CRYPT_INVALID_ARG;
116116
}
117117

118+
/* flags byte + nonce + length field must fit the 16-byte block */
119+
if ((noncelen + L) > 15) {
120+
return CRYPT_INVALID_ARG;
121+
}
122+
118123
/* allocate mem for the symmetric key */
119124
if (uskey == NULL) {
120125
skey = XMALLOC(sizeof(*skey));

‎src/encauth/ccm/ccm_test.c‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,50 @@ int ccm_test(void)
267267
}
268268
}
269269

270+
/* invalid nonce lengths and nonce/L combinations must be rejected not silently adjusted */
271+
{
272+
unsigned char key[16] = { 0 };
273+
unsigned char nonce[16] = { 0 };
274+
unsigned char pt[16] = { 0 };
275+
unsigned char ct[16];
276+
277+
/* CCM nonce is 7..13 bytes */
278+
taglen = 8;
279+
if (ccm_memory(idx, key, sizeof(key), NULL, nonce, 6, NULL, 0, pt, sizeof(pt), ct, tag, &taglen, CCM_ENCRYPT) != CRYPT_INVALID_ARG) {
280+
return CRYPT_FAIL_TESTVECTOR;
281+
}
282+
taglen = 8;
283+
if (ccm_memory(idx, key, sizeof(key), NULL, nonce, 14, NULL, 0, pt, sizeof(pt), ct, tag, &taglen, CCM_ENCRYPT) != CRYPT_INVALID_ARG) {
284+
return CRYPT_FAIL_TESTVECTOR;
285+
}
286+
if ((err = ccm_init(&ccm, idx, key, sizeof(key), sizeof(pt), 8, 0)) != CRYPT_OK) {
287+
return err;
288+
}
289+
if (ccm_add_nonce(&ccm, nonce, 6) != CRYPT_INVALID_ARG) {
290+
return CRYPT_FAIL_TESTVECTOR;
291+
}
292+
if ((err = ccm_init(&ccm, idx, key, sizeof(key), sizeof(pt), 8, 0)) != CRYPT_OK) {
293+
return err;
294+
}
295+
if (ccm_add_nonce(&ccm, nonce, 14) != CRYPT_INVALID_ARG) {
296+
return CRYPT_FAIL_TESTVECTOR;
297+
}
298+
/* ptlen >= 2^16 forces L=3, so a 13-byte nonce no longer fits B_0 (13+3 > 15) */
299+
if ((err = ccm_init(&ccm, idx, key, sizeof(key), 65536, 8, 0)) != CRYPT_OK) {
300+
return err;
301+
}
302+
if (ccm_add_nonce(&ccm, nonce, 13) != CRYPT_INVALID_ARG) {
303+
return CRYPT_FAIL_TESTVECTOR;
304+
}
305+
/* 12-byte nonce still fits (12+3 == 15) */
306+
if ((err = ccm_init(&ccm, idx, key, sizeof(key), 65536, 8, 0)) != CRYPT_OK) {
307+
return err;
308+
}
309+
if ((err = ccm_add_nonce(&ccm, nonce, 12)) != CRYPT_OK) {
310+
return err;
311+
}
312+
}
313+
270314
return CRYPT_OK;
271315
#endif
272316
}

0 commit comments

Comments
 (0)