Skip to content

Commit b08704c

Browse files
committed
FEAT: added support for CCM (Counter with CBC-MAC) cipher mode
1 parent 6c8d19e commit b08704c

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed

make/rebol3.nest

+8
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,13 @@ include-cipher-mode-gcm: [
482482
core-files: %core/mbedtls/cipher_wrap.c
483483
config: MBEDTLS_GCM_C
484484
]
485+
include-cipher-mode-ccm: [
486+
core-files: %core/mbedtls/ccm.c
487+
; CCM runs with multiple ciphers and internally uses the generic wrapper
488+
core-files: %core/mbedtls/cipher.c
489+
core-files: %core/mbedtls/cipher_wrap.c
490+
config: MBEDTLS_CCM_C
491+
]
485492
include-cipher-mode-cbc: [
486493
; costs cca 1.5kB uncompressed (for AES)
487494
config: MBEDTLS_CIPHER_MODE_CBC
@@ -586,6 +593,7 @@ include-cryptography: [
586593
:include-cipher-chacha20
587594
:include-cipher-chachapoly
588595
:include-cipher-mode-cbc
596+
:include-cipher-mode-ccm
589597
:include-cipher-mode-gcm
590598

591599
;:include-deprecated-cipher-chacha20

src/boot/words.reb

+10
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,16 @@ curve448 ; Curve448
309309

310310
init-vector
311311

312+
; the order is important!
312313
aes-128-ecb
313314
aes-192-ecb
314315
aes-256-ecb
315316
aes-128-cbc
316317
aes-192-cbc
317318
aes-256-cbc
319+
aes-128-ccm
320+
aes-192-ccm
321+
aes-256-ccm
318322
aes-128-gcm
319323
aes-192-gcm
320324
aes-256-gcm
@@ -324,6 +328,9 @@ camellia-256-ecb
324328
camellia-128-cbc
325329
camellia-192-cbc
326330
camellia-256-cbc
331+
camellia-128-ccm
332+
camellia-192-ccm
333+
camellia-256-ccm
327334
camellia-128-gcm
328335
camellia-192-gcm
329336
camellia-256-gcm
@@ -333,6 +340,9 @@ aria-256-ecb
333340
aria-128-cbc
334341
aria-192-cbc
335342
aria-256-cbc
343+
aria-128-ccm
344+
aria-192-ccm
345+
aria-256-ccm
336346
aria-128-gcm
337347
aria-192-gcm
338348
aria-256-gcm

src/core/n-crypt.c

+15
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ static mbedtls_ctr_drbg_context ctr_drbg;
9191
add_ec_word(SYM_AES_192_CBC)
9292
add_ec_word(SYM_AES_256_CBC)
9393
#endif
94+
#ifdef MBEDTLS_CCM_C
95+
add_ec_word(SYM_AES_128_CCM)
96+
add_ec_word(SYM_AES_192_CCM)
97+
add_ec_word(SYM_AES_256_CCM)
98+
#endif
9499
#ifdef MBEDTLS_GCM_C
95100
add_ec_word(SYM_AES_128_GCM)
96101
add_ec_word(SYM_AES_192_GCM)
@@ -105,6 +110,11 @@ static mbedtls_ctr_drbg_context ctr_drbg;
105110
add_ec_word(SYM_CAMELLIA_192_CBC)
106111
add_ec_word(SYM_CAMELLIA_256_CBC)
107112
#endif
113+
#ifdef MBEDTLS_CCM_C
114+
add_ec_word(SYM_CAMELLIA_128_CCM)
115+
add_ec_word(SYM_CAMELLIA_192_CCM)
116+
add_ec_word(SYM_CAMELLIA_256_CCM)
117+
#endif
108118
#ifdef MBEDTLS_GCM_C
109119
add_ec_word(SYM_CAMELLIA_128_GCM)
110120
add_ec_word(SYM_CAMELLIA_192_GCM)
@@ -120,6 +130,11 @@ static mbedtls_ctr_drbg_context ctr_drbg;
120130
add_ec_word(SYM_ARIA_192_CBC)
121131
add_ec_word(SYM_ARIA_256_CBC)
122132
#endif
133+
#ifdef MBEDTLS_CCM_C
134+
add_ec_word(SYM_ARIA_128_CCM)
135+
add_ec_word(SYM_ARIA_192_CCM)
136+
add_ec_word(SYM_ARIA_256_CCM)
137+
#endif
123138
#ifdef MBEDTLS_GCM_C
124139
add_ec_word(SYM_ARIA_128_GCM)
125140
add_ec_word(SYM_ARIA_192_GCM)

src/core/p-crypt.c

+111-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,31 @@
5050
)
5151
#endif
5252

53+
54+
/***********************************************************************
55+
**
56+
*/ static mbedtls_cipher_id_t get_cipher_id(REBCNT sym)
57+
/*
58+
** Note: requires exact word order defined in boot/words.reb file
59+
**
60+
***********************************************************************/
61+
{
62+
if (sym >= SYM_AES_128_ECB && sym <= SYM_AES_256_GCM) {
63+
return MBEDTLS_CIPHER_ID_AES;
64+
}
65+
if (sym >= SYM_CAMELLIA_128_ECB && sym <= SYM_CAMELLIA_256_GCM) {
66+
return MBEDTLS_CIPHER_ID_CAMELLIA;
67+
}
68+
if (sym >= SYM_ARIA_128_ECB && sym <= SYM_ARIA_256_GCM) {
69+
return MBEDTLS_CIPHER_ID_ARIA;
70+
}
71+
if (sym >= SYM_CHACHA20 && sym <= SYM_CHACHA20_POLY1305) {
72+
return MBEDTLS_CIPHER_ID_CHACHA20;
73+
}
74+
return MBEDTLS_CIPHER_ID_NULL;
75+
}
76+
77+
5378
static void free_crypt_cipher_context(CRYPT_CTX *ctx);
5479

5580

@@ -117,6 +142,7 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
117142
if (IS_NONE(val)) {
118143
CLEAR(&ctx->IV, MBEDTLS_MAX_IV_LENGTH);
119144
CLEAR(&ctx->nonce, MBEDTLS_MAX_IV_LENGTH);
145+
ctx->IV_len = 0;
120146
return TRUE;
121147
}
122148
if (IS_BINARY(val)) {
@@ -127,6 +153,7 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
127153
CLEAR(&ctx->IV, MBEDTLS_MAX_IV_LENGTH);
128154
CLEAR(&ctx->nonce, MBEDTLS_MAX_IV_LENGTH);
129155
COPY_MEM(&ctx->IV, VAL_BIN_AT(val), len);
156+
ctx->IV_len = len;
130157
}
131158
return TRUE;
132159
}
@@ -255,6 +282,39 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
255282
ctx->cipher_block_size = 16;
256283
break;
257284

285+
#ifdef MBEDTLS_CCM_C
286+
case SYM_AES_128_CCM:
287+
case SYM_AES_192_CCM:
288+
case SYM_AES_256_CCM:
289+
#ifdef MBEDTLS_CAMELLIA_C
290+
case SYM_CAMELLIA_128_CCM:
291+
case SYM_CAMELLIA_192_CCM:
292+
case SYM_CAMELLIA_256_CCM:
293+
#endif
294+
#ifdef MBEDTLS_ARIA_C
295+
case SYM_ARIA_128_CCM:
296+
case SYM_ARIA_192_CCM:
297+
case SYM_ARIA_256_CCM:
298+
#endif
299+
if (ctx->cipher_ctx == NULL)
300+
ctx->cipher_ctx = malloc(sizeof(mbedtls_ccm_context));
301+
mbedtls_ccm_init((mbedtls_ccm_context*)ctx->cipher_ctx);
302+
switch (type) {
303+
case SYM_AES_128_CCM:
304+
case SYM_ARIA_128_CCM:
305+
case SYM_CAMELLIA_128_CCM: ctx->key_bitlen = 128; break;
306+
case SYM_AES_192_CCM:
307+
case SYM_ARIA_192_CCM:
308+
case SYM_CAMELLIA_192_CCM: ctx->key_bitlen = 192; break;
309+
case SYM_AES_256_CCM:
310+
case SYM_ARIA_256_CCM:
311+
case SYM_CAMELLIA_256_CCM: ctx->key_bitlen = 256; break;
312+
}
313+
ctx->cipher_block_size = 0;
314+
break;
315+
316+
#endif
317+
258318
#ifdef MBEDTLS_GCM_C
259319
case SYM_AES_128_GCM:
260320
case SYM_AES_192_GCM:
@@ -466,6 +526,30 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
466526
break;
467527
#endif
468528

529+
#ifdef MBEDTLS_CCM_C
530+
case SYM_AES_128_CCM:
531+
case SYM_AES_192_CCM:
532+
case SYM_AES_256_CCM:
533+
#ifdef MBEDTLS_CAMELLIA_C
534+
case SYM_CAMELLIA_128_CCM:
535+
case SYM_CAMELLIA_192_CCM:
536+
case SYM_CAMELLIA_256_CCM:
537+
#endif
538+
#ifdef MBEDTLS_ARIA_C
539+
case SYM_ARIA_128_CCM:
540+
case SYM_ARIA_192_CCM:
541+
case SYM_ARIA_256_CCM:
542+
#endif
543+
{
544+
size_t out_bytes = 0;
545+
err = mbedtls_ccm_update((mbedtls_ccm_context*)ctx->cipher_ctx, input, len, BIN_TAIL(bin), len, &out_bytes);
546+
if (err) return err;
547+
SERIES_TAIL(bin) += out_bytes;
548+
input += out_bytes;
549+
break;
550+
}
551+
#endif
552+
469553
#ifdef MBEDTLS_GCM_C
470554
case SYM_AES_128_GCM:
471555
case SYM_AES_192_GCM:
@@ -589,6 +673,7 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
589673
return CRYPT_OK;
590674
}
591675

676+
592677
/***********************************************************************
593678
**
594679
*/ static REBINT Crypt_Init(CRYPT_CTX *ctx)
@@ -619,6 +704,31 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
619704
}
620705
break;
621706

707+
#ifdef MBEDTLS_CCM_C
708+
case SYM_AES_128_CCM:
709+
case SYM_AES_192_CCM:
710+
case SYM_AES_256_CCM:
711+
#ifdef MBEDTLS_CAMELLIA_C
712+
case SYM_CAMELLIA_128_CCM:
713+
case SYM_CAMELLIA_192_CCM:
714+
case SYM_CAMELLIA_256_CCM:
715+
#endif
716+
#ifdef MBEDTLS_ARIA_C
717+
case SYM_ARIA_128_CCM:
718+
case SYM_ARIA_192_CCM:
719+
case SYM_ARIA_256_CCM:
720+
#endif
721+
{
722+
mbedtls_ccm_context* ccm = (mbedtls_ccm_context*)ctx->cipher_ctx;
723+
err = mbedtls_ccm_setkey(ccm, get_cipher_id(ctx->cipher_type), ctx->key, ctx->key_bitlen);
724+
if (err) return err;
725+
ctx->IV_len = MAX(7, MIN(13, ctx->IV_len));
726+
err = mbedtls_ccm_starts(ccm, ctx->operation, ctx->IV, ctx->IV_len);
727+
ctx->unprocessed_len = 0;
728+
break;
729+
}
730+
#endif
731+
622732
#ifdef MBEDTLS_GCM_C
623733
case SYM_AES_128_GCM:
624734
case SYM_AES_192_GCM:
@@ -635,7 +745,7 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
635745
#endif
636746
{
637747
mbedtls_gcm_context *gcm = (mbedtls_gcm_context *)ctx->cipher_ctx;
638-
err = mbedtls_gcm_setkey(gcm, MBEDTLS_CIPHER_ID_AES, ctx->key, ctx->key_bitlen);
748+
err = mbedtls_gcm_setkey(gcm, get_cipher_id(ctx->cipher_type), ctx->key, ctx->key_bitlen);
639749
if (err) return err;
640750
err = mbedtls_gcm_starts(gcm, ctx->operation, ctx->IV, 16);
641751
ctx->unprocessed_len = 0;

src/include/sys-crypt.h

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ typedef mbedtls_chachapoly_context CHACHAPOLY_CTX;
6262
#define CHACHAPOLY_STATE_CIPHERTEXT (2)
6363
#endif
6464

65+
#ifdef MBEDTLS_CCM_C
66+
#include "mbedtls/ccm.h"
67+
#endif
68+
6569
#ifdef MBEDTLS_GCM_C
6670
#include "mbedtls/gcm.h"
6771
#endif
@@ -95,6 +99,7 @@ typedef struct crypt_ctx {
9599
void *cipher_ctx;
96100
REBSER *buffer;
97101
unsigned int key_bitlen;
102+
unsigned int IV_len;
98103
unsigned int unprocessed_len;
99104
unsigned char nonce[MBEDTLS_MAX_IV_LENGTH]; // nonce may be changed, like in Camellia cipher!
100105
unsigned char IV[MBEDTLS_MAX_IV_LENGTH];

0 commit comments

Comments
 (0)