Skip to content

Commit f1a82b1

Browse files
committed
FEAT: added support for authentication in GCM (Galois/Counter mode) cipher mode
1 parent e4d80cb commit f1a82b1

File tree

4 files changed

+694
-5
lines changed

4 files changed

+694
-5
lines changed

src/core/p-crypt.c

+31-5
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
336336
if (ctx->cipher_ctx == NULL)
337337
ctx->cipher_ctx = malloc(sizeof(mbedtls_gcm_context));
338338
mbedtls_gcm_init((mbedtls_gcm_context *)ctx->cipher_ctx);
339+
ctx->cipher_mode = MBEDTLS_MODE_GCM;
339340
switch (type) {
340341
case SYM_AES_128_GCM:
341342
case SYM_ARIA_128_GCM:
@@ -494,8 +495,6 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
494495

495496
*olen = 0;
496497

497-
if (len == 0) return 0;
498-
499498
bin = ctx->buffer;
500499
blk = ctx->cipher_block_size;
501500

@@ -610,6 +609,14 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
610609
#endif
611610
{
612611
size_t out_bytes = 0;
612+
613+
if (ctx->state == CRYPT_PORT_NO_DATA && ctx->aad_len) {
614+
if (len < ctx->aad_len) return 1;
615+
err = mbedtls_gcm_update_ad((mbedtls_gcm_context *)ctx->cipher_ctx, input, ctx->aad_len);
616+
if (err) return err;
617+
input += ctx->aad_len;
618+
len -= ctx->aad_len;
619+
}
613620
err = mbedtls_gcm_update((mbedtls_gcm_context *)ctx->cipher_ctx, input, len, BIN_TAIL(bin), len, &out_bytes);
614621
if (err) return err;
615622
SERIES_TAIL(bin) += out_bytes;
@@ -876,7 +883,7 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
876883
REBSER* bin;
877884
REBCNT len, ofs, blk;
878885
REBINT ret = CRYPT_OK;
879-
REBCNT olen = 0;
886+
size_t olen = 0;
880887

881888
bin = ctx->buffer;
882889

@@ -910,6 +917,19 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
910917
ret = Crypt_Crypt(ctx, ctx->unprocessed_data, blk, &olen);
911918
ctx->unprocessed_len = 0;
912919
}
920+
if (ctx->tag_len) {
921+
#ifdef MBEDTLS_GCM_C
922+
if (ctx->cipher_mode == MBEDTLS_MODE_GCM) {
923+
// compute tag
924+
Extend_Series(bin, ctx->tag_len);
925+
ret = mbedtls_gcm_finish((mbedtls_gcm_context*)ctx->cipher_ctx, NULL, 0, &olen, BIN_TAIL(bin), ctx->tag_len);
926+
if (ret) return ret;
927+
SERIES_TAIL(bin) += ctx->tag_len;
928+
ctx->state = CRYPT_PORT_FINISHED;
929+
}
930+
#endif
931+
}
932+
913933
return ret;
914934
}
915935

@@ -923,13 +943,19 @@ static void free_crypt_cipher_context(CRYPT_CTX *ctx);
923943
REBCNT blk, olen;
924944
REBCNT unprocessed_free;
925945

926-
if (len == 0) return 0;
927-
928946
if (ctx->state == CRYPT_PORT_NEEDS_INIT) {
929947
ret = Crypt_Init(ctx);
930948
if (ret) return ret;
931949
}
932950

951+
if (len == 0) {
952+
// it is valid to encrypt empty message
953+
if (ctx->cipher_mode == MBEDTLS_MODE_GCM) {
954+
ret = Crypt_Crypt(ctx, input, 0, &olen);
955+
}
956+
return ret;
957+
}
958+
933959
blk = ctx->cipher_block_size;
934960
if (blk > MBEDTLS_MAX_BLOCK_LENGTH) return CRYPT_ERROR_BAD_BLOCK_SIZE;
935961

src/tests/run-tests.r3

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ dt [ ;- delta time
7373
%units/crypt-test.r3
7474
%units/crypt-port-test.r3
7575
%units/crypt-port-camelia-test.r3
76+
%units/crypt-port-ccm-test.r3
77+
%units/crypt-port-gcm-test.r3
7678
%units/poly1305-test.r3
7779
%units/rc4-test.r3
7880
%units/rsa-test.r3

0 commit comments

Comments
 (0)