Skip to content

Commit 9a1131d

Browse files
committed
add tag validation to chacha20poly1305_memory in decrypt mode
1 parent fd4d8fb commit 9a1131d

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

src/encauth/chachapoly/chacha20poly1305_memory.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
4343
LTC_ARGCHK(in != NULL);
4444
LTC_ARGCHK(out != NULL);
4545
LTC_ARGCHK(tag != NULL);
46+
LTC_ARGCHK(taglen != NULL);
4647

4748
if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; }
4849
if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; }
@@ -51,15 +52,22 @@ int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
5152
}
5253
if (direction == CHACHA20POLY1305_ENCRYPT) {
5354
if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
55+
if ((err = chacha20poly1305_done(&st, tag, taglen)) != CRYPT_OK) { goto LBL_ERR; }
5456
}
5557
else if (direction == CHACHA20POLY1305_DECRYPT) {
58+
unsigned char buf[MAXBLOCKSIZE];
59+
unsigned long buflen = sizeof(buf);
5660
if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
61+
if ((err = chacha20poly1305_done(&st, buf, &buflen)) != CRYPT_OK) { goto LBL_ERR; }
62+
if (buflen != *taglen || XMEM_NEQ(buf, tag, buflen) != 0) {
63+
err = CRYPT_ERROR;
64+
goto LBL_ERR;
65+
}
5766
}
5867
else {
5968
err = CRYPT_INVALID_ARG;
6069
goto LBL_ERR;
6170
}
62-
err = chacha20poly1305_done(&st, tag, taglen);
6371
LBL_ERR:
6472
#ifdef LTC_CLEAN_STACK
6573
zeromem(&st, sizeof(chacha20poly1305_state));

src/encauth/chachapoly/chacha20poly1305_test.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ int chacha20poly1305_test(void)
7777

7878
/* chacha20poly1305_memory - decrypt */
7979
len = sizeof(dmac);
80+
XMEMCPY(dmac, tag, sizeof(tag));
8081
if ((err = chacha20poly1305_memory(k, sizeof(k), i12, sizeof(i12), aad, sizeof(aad),
8182
ct, mlen, pt, dmac, &len, CHACHA20POLY1305_DECRYPT)) != CRYPT_OK) return err;
8283
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT2", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
83-
if (compare_testvector(dmac, len, tag, sizeof(tag), "DEC-TAG2", 4) != 0) return CRYPT_FAIL_TESTVECTOR;
8484

8585
/* encrypt - rfc7905 */
8686
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
@@ -123,6 +123,41 @@ int chacha20poly1305_test(void)
123123
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT4", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
124124
if (compare_testvector(dmac, len, emac, len, "DEC-TAG4", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
125125

126+
/* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/451 */
127+
{
128+
unsigned char key[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,
129+
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
130+
unsigned char iv[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b };
131+
unsigned char valid_tag[] = { 0xa3,0xe3,0xfd,0xf9,0xfb,0xa6,0x86,0x1b,0x5a,0xd2,0x60,0x7f,0x40,0xb7,0xf4,0x47 };
132+
unsigned char invalid_tag[] = { 0xa2,0xe3,0xfd,0xf9,0xfb,0xa6,0x86,0x1b,0x5a,0xd2,0x60,0x7f,0x40,0xb7,0xf4,0x47 };
133+
unsigned char waad[] = { 0x61,0x61,0x64 };
134+
unsigned char wct[] = { 0x00 };
135+
unsigned char wpt[20] = { 0 };
136+
unsigned char wtag[20] = { 0 };
137+
unsigned long taglen;
138+
139+
/* encrypt */
140+
taglen = sizeof(wtag);
141+
err = chacha20poly1305_memory(key, sizeof(key), iv, sizeof(iv), waad, sizeof(waad),
142+
wpt, 0, wct, wtag, &taglen, CHACHA20POLY1305_ENCRYPT);
143+
if (err != CRYPT_OK) return CRYPT_FAIL_TESTVECTOR;
144+
if (compare_testvector(wtag, taglen, valid_tag, sizeof(valid_tag), "WYCH", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
145+
146+
/* VALID tag */
147+
taglen = sizeof(valid_tag);
148+
err = chacha20poly1305_memory(key, sizeof(key), iv, sizeof(iv), waad, sizeof(waad),
149+
wpt, 0, wct, valid_tag, &taglen, CHACHA20POLY1305_DECRYPT);
150+
if (err != CRYPT_OK) return CRYPT_FAIL_TESTVECTOR;
151+
152+
/* INVALID tag */
153+
taglen = sizeof(invalid_tag);
154+
err = chacha20poly1305_memory(key, sizeof(key), iv, sizeof(iv), waad, sizeof(waad),
155+
wpt, 0, wct, invalid_tag, &taglen, CHACHA20POLY1305_DECRYPT);
156+
if (err == CRYPT_OK) {
157+
return CRYPT_FAIL_TESTVECTOR; /* should fail */
158+
}
159+
}
160+
126161
return CRYPT_OK;
127162
#endif
128163
}

0 commit comments

Comments
 (0)