|
@@ -114,10 +114,12 @@ int ccm_test(void)
|
|
|
|
|
|
};
|
|
|
unsigned long taglen, x, y;
|
|
|
- unsigned char buf[64], buf2[64], tag2[16], tag[16];
|
|
|
+ unsigned char buf[64], buf2[64], tag[16], tag2[16], tag3[16], zero[64];
|
|
|
int err, idx;
|
|
|
symmetric_key skey;
|
|
|
ccm_state ccm;
|
|
|
+
|
|
|
+ zeromem(zero, 64);
|
|
|
|
|
|
idx = find_cipher("aes");
|
|
|
if (idx == -1) {
|
|
@@ -166,8 +168,8 @@ int ccm_test(void)
|
|
|
if (XMEMCMP(buf, tests[x].ct, tests[x].ptlen)) {
|
|
|
#if defined(LTC_TEST_DBG)
|
|
|
printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
|
|
|
- print_hex("ct is ", tag, taglen);
|
|
|
- print_hex("ct should", tests[x].tag, taglen);
|
|
|
+ print_hex("ct is ", buf, tests[x].ptlen);
|
|
|
+ print_hex("ct should", tests[x].ct, tests[x].ptlen);
|
|
|
#endif
|
|
|
return CRYPT_FAIL_TESTVECTOR;
|
|
|
}
|
|
@@ -188,14 +190,16 @@ int ccm_test(void)
|
|
|
}
|
|
|
|
|
|
if (y == 0) {
|
|
|
- if ((err = ccm_memory(idx,
|
|
|
+ XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
|
|
|
+ taglen = tests[x].taglen;
|
|
|
+ if ((err = ccm_memory(idx,
|
|
|
tests[x].key, 16,
|
|
|
NULL,
|
|
|
tests[x].nonce, tests[x].noncelen,
|
|
|
tests[x].header, tests[x].headerlen,
|
|
|
buf2, tests[x].ptlen,
|
|
|
buf,
|
|
|
- tag2, &taglen, 1 )) != CRYPT_OK) {
|
|
|
+ tag3, &taglen, 1 )) != CRYPT_OK) {
|
|
|
return err;
|
|
|
}
|
|
|
} else {
|
|
@@ -219,24 +223,56 @@ int ccm_test(void)
|
|
|
if (XMEMCMP(buf2, tests[x].pt, tests[x].ptlen)) {
|
|
|
#if defined(LTC_TEST_DBG)
|
|
|
printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
|
|
|
- print_hex("pt is ", tag, taglen);
|
|
|
- print_hex("pt should", tests[x].tag, taglen);
|
|
|
+ print_hex("pt is ", buf2, tests[x].ptlen);
|
|
|
+ print_hex("pt should", tests[x].pt, tests[x].ptlen);
|
|
|
#endif
|
|
|
return CRYPT_FAIL_TESTVECTOR;
|
|
|
}
|
|
|
- if (XMEMCMP(tag2, tests[x].tag, tests[x].taglen)) {
|
|
|
+ if (y == 0) {
|
|
|
+ /* check if decryption with the wrong tag does not reveal the plaintext */
|
|
|
+ XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
|
|
|
+ tag3[0] ^= 0xff; /* set the tag to the wrong value */
|
|
|
+ taglen = tests[x].taglen;
|
|
|
+ if ((err = ccm_memory(idx,
|
|
|
+ tests[x].key, 16,
|
|
|
+ NULL,
|
|
|
+ tests[x].nonce, tests[x].noncelen,
|
|
|
+ tests[x].header, tests[x].headerlen,
|
|
|
+ buf2, tests[x].ptlen,
|
|
|
+ buf,
|
|
|
+ tag3, &taglen, 1 )) != CRYPT_ERROR) {
|
|
|
+ return CRYPT_FAIL_TESTVECTOR;
|
|
|
+ }
|
|
|
+ if (XMEMCMP(buf2, zero, tests[x].ptlen)) {
|
|
|
+#if defined(LTC_CCM_TEST_DBG)
|
|
|
+ printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
|
|
|
+ print_hex("pt is ", buf2, tests[x].ptlen);
|
|
|
+ print_hex("pt should", zero, tests[x].ptlen);
|
|
|
+#endif
|
|
|
+ return CRYPT_FAIL_TESTVECTOR;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* FIXME: Only check the tag if ccm_memory was not called: ccm_memory already
|
|
|
+ validates the tag. ccm_process and ccm_done should somehow do the same,
|
|
|
+ although with current setup it is impossible to keep the plaintext hidden
|
|
|
+ if the tag is incorrect.
|
|
|
+ */
|
|
|
+ if (XMEMCMP(tag2, tests[x].tag, tests[x].taglen)) {
|
|
|
#if defined(LTC_TEST_DBG)
|
|
|
- printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
|
|
|
- print_hex("tag is ", tag, tests[x].taglen);
|
|
|
- print_hex("tag should", tests[x].tag, tests[x].taglen);
|
|
|
+ printf("\n%d: x=%lu y=%lu\n", __LINE__, x, y);
|
|
|
+ print_hex("tag is ", tag2, tests[x].taglen);
|
|
|
+ print_hex("tag should", tests[x].tag, tests[x].taglen);
|
|
|
#endif
|
|
|
- return CRYPT_FAIL_TESTVECTOR;
|
|
|
+ return CRYPT_FAIL_TESTVECTOR;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
if (y == 0) {
|
|
|
cipher_descriptor[idx].done(&skey);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return CRYPT_OK;
|
|
|
#endif
|
|
|
}
|