Skip to content

Commit c4aac63

Browse files
authored
Proper state management for AES GCM and CCM (microsoft#112)
* Only reset IV for new IV length. Track iv and tag state in ccm * Update tagSet after ccm encrypt * Free rsa private exponent in import * Secure malloc and free primes and private exponent
1 parent 5b08f1c commit c4aac63

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

ScosslCommon/inc/scossl_aes_aead.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ typedef struct
8888
SCOSSL_CCM_STAGE ccmStage;
8989
BYTE iv[SCOSSL_CCM_MAX_IV_LENGTH];
9090
SIZE_T ivlen;
91+
INT32 ivSet;
9192
SYMCRYPT_CCM_STATE state;
9293
SYMCRYPT_AES_EXPANDED_KEY key;
9394
BYTE tag[EVP_CCM_TLS_TAG_LEN];
9495
SIZE_T taglen;
96+
INT32 tagSet;
9597
UINT64 cbData;
9698
BYTE tlsAad[EVP_AEAD_TLS1_AAD_LEN];
9799
INT32 tlsAadSet;

ScosslCommon/src/scossl_aes_aead.c

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,15 @@ SCOSSL_STATUS scossl_aes_gcm_set_iv_len(SCOSSL_CIPHER_GCM_CTX *ctx, size_t ivlen
287287
return SCOSSL_FAILURE;
288288
}
289289

290-
ctx->ivlen = ivlen;
291-
292-
if (ctx->iv != NULL)
290+
if (ivlen != ctx->ivlen)
293291
{
294-
OPENSSL_free(ctx->iv);
295-
ctx->iv = NULL;
292+
ctx->ivlen = ivlen;
293+
294+
if (ctx->iv != NULL)
295+
{
296+
OPENSSL_free(ctx->iv);
297+
ctx->iv = NULL;
298+
}
296299
}
297300

298301
return SCOSSL_SUCCESS;
@@ -429,6 +432,8 @@ void scossl_aes_ccm_init_ctx(SCOSSL_CIPHER_CCM_CTX *ctx,
429432
memcpy(ctx->iv, iv, ctx->ivlen);
430433
}
431434
ctx->taglen = SCOSSL_CCM_MAX_TAG_LENGTH;
435+
ctx->ivSet = 0;
436+
ctx->tagSet = 0;
432437
ctx->tlsAadSet = 0;
433438
}
434439

@@ -450,6 +455,7 @@ SCOSSL_STATUS scossl_aes_ccm_init_key(SCOSSL_CIPHER_CCM_CTX *ctx,
450455

451456
ctx->ivlen = ivlen;
452457
memcpy(ctx->iv, iv, ctx->ivlen);
458+
ctx->ivSet = 1;
453459
}
454460
if (key)
455461
{
@@ -618,6 +624,13 @@ SCOSSL_STATUS scossl_aes_ccm_cipher(SCOSSL_CIPHER_CCM_CTX *ctx, INT32 encrypt,
618624

619625
if (ctx->ccmStage == SCOSSL_CCM_STAGE_SET_CBDATA)
620626
{
627+
if (!ctx->ivSet)
628+
{
629+
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_AES_CCM_CIPHER, ERR_R_PASSED_INVALID_ARGUMENT,
630+
"No IV provided to CCM");
631+
return SCOSSL_FAILURE;
632+
}
633+
621634
if (out == NULL)
622635
{
623636
// Auth Data Passed in
@@ -653,10 +666,17 @@ SCOSSL_STATUS scossl_aes_ccm_cipher(SCOSSL_CIPHER_CCM_CTX *ctx, INT32 encrypt,
653666
SymCryptCcmEncryptPart(&ctx->state, in, out, inl);
654667
}
655668
SymCryptCcmEncryptFinal(&ctx->state, ctx->tag, ctx->taglen);
669+
ctx->tagSet = 1;
656670
ctx->ccmStage = SCOSSL_CCM_STAGE_COMPLETE;
657671
}
658672
else
659673
{
674+
if (!ctx->tagSet)
675+
{
676+
SCOSSL_LOG_ERROR(SCOSSL_ERR_F_AES_CCM_CIPHER, ERR_R_PASSED_INVALID_ARGUMENT,
677+
"No tag provided to CCM Decrypt");
678+
return SCOSSL_FAILURE;
679+
}
660680
// Decryption
661681
if (in != NULL)
662682
{
@@ -680,7 +700,7 @@ SCOSSL_STATUS scossl_aes_ccm_get_aead_tag(SCOSSL_CIPHER_CCM_CTX *ctx, INT32 encr
680700
unsigned char *tag, size_t taglen)
681701
{
682702
if ((taglen & 1) || taglen < SCOSSL_CCM_MIN_TAG_LENGTH || taglen > SCOSSL_CCM_MAX_TAG_LENGTH ||
683-
taglen > ctx->taglen || !encrypt)
703+
taglen > ctx->taglen || !encrypt || !ctx->tagSet)
684704
{
685705
return SCOSSL_FAILURE;
686706
}
@@ -702,6 +722,7 @@ SCOSSL_STATUS scossl_aes_ccm_set_aead_tag(SCOSSL_CIPHER_CCM_CTX *ctx, INT32 encr
702722
memcpy(ctx->tag, tag, taglen);
703723
}
704724
ctx->taglen = taglen;
725+
ctx->tagSet = 1;
705726

706727
return SCOSSL_SUCCESS;
707728
}
@@ -717,7 +738,12 @@ SCOSSL_STATUS scossl_aes_ccm_set_iv_len(SCOSSL_CIPHER_CCM_CTX *ctx, size_t ivlen
717738
return SCOSSL_FAILURE;
718739
}
719740

720-
ctx->ivlen = ivlen;
741+
if (ctx->ivlen != ivlen)
742+
{
743+
ctx->ivlen = ivlen;
744+
ctx->ivSet = 0;
745+
}
746+
721747
return SCOSSL_SUCCESS;
722748
}
723749

@@ -751,6 +777,8 @@ SCOSSL_STATUS scossl_aes_ccm_set_iv_fixed(SCOSSL_CIPHER_CCM_CTX *ctx, INT32 encr
751777
return SCOSSL_FAILURE;
752778
}
753779

780+
ctx->ivSet = 1;
781+
754782
return SCOSSL_SUCCESS;
755783
}
756784

SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,8 +1064,8 @@ static BOOL p_scossl_rsa_keymgmt_match(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx1, _I
10641064
cleanup:
10651065
OPENSSL_free(pbModulus1);
10661066
OPENSSL_free(pbModulus2);
1067-
OPENSSL_secure_free(pbPrivateExponent1);
1068-
OPENSSL_secure_free(pbPrivateExponent2);
1067+
OPENSSL_secure_clear_free(pbPrivateExponent1, cbModulus);
1068+
OPENSSL_secure_clear_free(pbPrivateExponent2, cbModulus);
10691069

10701070
return ret;
10711071
}
@@ -1114,7 +1114,7 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_PROV_RSA_KEY_CTX
11141114
{
11151115
cbModulus = p->data_size;
11161116

1117-
pbModulus = OPENSSL_zalloc(cbModulus);
1117+
pbModulus = OPENSSL_malloc(cbModulus);
11181118
if (pbModulus == NULL)
11191119
{
11201120
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
@@ -1141,7 +1141,7 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_PROV_RSA_KEY_CTX
11411141
{
11421142
pcbPrimes[0] = p->data_size;
11431143

1144-
ppbPrimes[0] = OPENSSL_zalloc(pcbPrimes[0]);
1144+
ppbPrimes[0] = OPENSSL_secure_malloc(pcbPrimes[0]);
11451145
if (ppbPrimes[0] == NULL)
11461146
{
11471147
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
@@ -1160,7 +1160,7 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_PROV_RSA_KEY_CTX
11601160
{
11611161
pcbPrimes[1] = p->data_size;
11621162

1163-
ppbPrimes[1] = OPENSSL_zalloc(pcbPrimes[1]);
1163+
ppbPrimes[1] = OPENSSL_secure_malloc(pcbPrimes[1]);
11641164
if(ppbPrimes[1] == NULL)
11651165
{
11661166
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
@@ -1182,7 +1182,7 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_PROV_RSA_KEY_CTX
11821182
{
11831183
cbPrivateExponent = p->data_size;
11841184

1185-
pbPrivateExponent = OPENSSL_zalloc(cbPrivateExponent);
1185+
pbPrivateExponent = OPENSSL_secure_malloc(cbPrivateExponent);
11861186
if(pbPrivateExponent == NULL)
11871187
{
11881188
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
@@ -1271,9 +1271,10 @@ static SCOSSL_STATUS p_scossl_rsa_keymgmt_import(_Inout_ SCOSSL_PROV_RSA_KEY_CTX
12711271
ret = SCOSSL_SUCCESS;
12721272

12731273
cleanup:
1274+
OPENSSL_secure_clear_free(pbPrivateExponent, cbModulus);
1275+
OPENSSL_secure_clear_free(ppbPrimes[0], pcbPrimes[0]);
1276+
OPENSSL_secure_clear_free(ppbPrimes[1], pcbPrimes[1]);
12741277
OPENSSL_free(pbModulus);
1275-
OPENSSL_free(ppbPrimes[0]);
1276-
OPENSSL_free(ppbPrimes[1]);
12771278
BN_free(bn);
12781279

12791280
return ret;

0 commit comments

Comments
 (0)