diff --git a/src/encauth/siv/siv.c b/src/encauth/siv/siv.c index bd6d5b45b..d2e6e1658 100644 --- a/src/encauth/siv/siv.c +++ b/src/encauth/siv/siv.c @@ -191,7 +191,8 @@ static int s_siv_S2V(int cipher, return err; } - do { + /* With zero AD components the loop runs zero times. */ + while (n < adnum) { if (n >= s_siv_max_aad_components) { return CRYPT_INPUT_TOO_LONG; } @@ -199,7 +200,7 @@ static int s_siv_S2V(int cipher, return err; } n++; - } while(n < adnum); + } return s_siv_S2V_T(&ctx, in, inlen, &D, V); } @@ -470,23 +471,19 @@ int siv_memory( int cipher, int direction, goto err_out; } va_start(args, adnum); - do { - if (adnum) { - aad = va_arg(args, const unsigned char*); - aadlen = va_arg(args, unsigned long); - } else { - aad = NULL; - aadlen = 0; - } + /* With zero AD components the loop runs zero times. */ + while (n < adnum) { if (n >= s_siv_max_aad_components) { err = CRYPT_INPUT_TOO_LONG; goto err_out2; } + aad = va_arg(args, const unsigned char*); + aadlen = va_arg(args, unsigned long); if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, aad, aadlen, &D)) != CRYPT_OK) { goto err_out2; } n++; - } while (n < adnum); + } if ((err = s_siv_S2V_T(&ctx, in_work, in_work_len, &D, &siv.V)) != CRYPT_OK) { goto err_out2; @@ -549,6 +546,13 @@ int siv_test(void) unsigned long adlen_A1[] = { sizeof(AD_A1), 0 }; + /* Key_A1/Plaintext_A1 with zero AD components */ + const unsigned char output_A1_noad[] = + { 0xf1, 0xc5, 0xfd, 0xea, 0xc1, 0xf1, 0x5a, 0x26, + 0x77, 0x9c, 0x15, 0x01, 0xf9, 0xfb, 0x75, 0x88, + 0x27, 0xe9, 0x46, 0xc6, 0x69, 0x08, 0x8a, 0xb0, + 0x6d, 0xa5, 0x8c, 0x5c, 0x83, 0x1c }; + const unsigned char Key_A2[] = { 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, @@ -736,6 +740,36 @@ int siv_test(void) return CRYPT_FAIL_TESTVECTOR; } + /* Zero AD components */ + buflen = sizeof(buf); + if ((err = siv_encrypt_memory(cipher, Key_A1, sizeof(Key_A1), 0, NULL, NULL, Plaintext_A1, sizeof(Plaintext_A1), buf, &buflen)) != CRYPT_OK) { + return err; + } + if (ltc_compare_testvector(buf, buflen, output_A1_noad, sizeof(output_A1_noad), "SIV encrypt no AD", 0x5000) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + buflen = sizeof(buf); + if ((err = siv_decrypt_memory(cipher, Key_A1, sizeof(Key_A1), 0, NULL, NULL, output_A1_noad, sizeof(output_A1_noad), buf, &buflen)) != CRYPT_OK) { + return err; + } + if (ltc_compare_testvector(buf, buflen, Plaintext_A1, sizeof(Plaintext_A1), "SIV decrypt no AD", 0x5001) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + buflen = sizeof(buf); + if ((err = siv_memory(cipher, LTC_ENCRYPT, Key_A1, sizeof(Key_A1), Plaintext_A1, sizeof(Plaintext_A1), buf, &buflen, 0, NULL)) != CRYPT_OK) { + return err; + } + if (ltc_compare_testvector(buf, buflen, output_A1_noad, sizeof(output_A1_noad), "siv_memory encrypt no AD", 0x5002) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + buflen = sizeof(buf); + if ((err = siv_memory(cipher, LTC_DECRYPT, Key_A1, sizeof(Key_A1), output_A1_noad, sizeof(output_A1_noad), buf, &buflen, 0, NULL)) != CRYPT_OK) { + return err; + } + if (ltc_compare_testvector(buf, buflen, Plaintext_A1, sizeof(Plaintext_A1), "siv_memory decrypt no AD", 0x5003) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + for (n = 0; n < LTC_ARRAY_SIZE(tmp); ++n) { tmp[n] = XCALLOC(1, tmpmax); if (tmp[n] == NULL) {