diff --git a/src/ltc/encauth/ccm/ccm_init.c b/src/ltc/encauth/ccm/ccm_init.c index 20c2a17..b1bd12d 100644 --- a/src/ltc/encauth/ccm/ccm_init.c +++ b/src/ltc/encauth/ccm/ccm_init.c @@ -29,7 +29,6 @@ LTC_ARGCHK(ccm != NULL); LTC_ARGCHK(key != NULL); - LTC_ARGCHK(taglen != 0); XMEMSET(ccm, 0, sizeof(ccm_state)); @@ -41,17 +40,11 @@ return CRYPT_INVALID_CIPHER; } - /* make sure the taglen is even and <= 16 */ - ccm->taglen = taglen; - ccm->taglen &= ~1; - if (ccm->taglen > 16) { - ccm->taglen = 16; - } - - /* can't use < 4 */ - if (ccm->taglen < 4) { + /* make sure the taglen is valid */ + if (taglen < 4 || taglen > 16 || (taglen % 2) == 1) { return CRYPT_INVALID_ARG; } + ccm->taglen = taglen; /* schedule key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ccm->K)) != CRYPT_OK) { diff --git a/src/ltc/encauth/ccm/ccm_memory.c b/src/ltc/encauth/ccm/ccm_memory.c index 40ecba6..7280133 100644 --- a/src/ltc/encauth/ccm/ccm_memory.c +++ b/src/ltc/encauth/ccm/ccm_memory.c @@ -80,14 +80,8 @@ return CRYPT_INVALID_CIPHER; } - /* make sure the taglen is even and <= 16 */ - *taglen &= ~1; - if (*taglen > 16) { - *taglen = 16; - } - - /* can't use < 4 */ - if (*taglen < 4) { + /* make sure the taglen is valid */ + if (*taglen < 4 || *taglen > 16 || (*taglen % 2) == 1) { return CRYPT_INVALID_ARG; } diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c b/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c index f19cf18..493404f 100644 --- a/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c @@ -25,7 +25,6 @@ unsigned long padlen; int err; - if (inlen == 0) return CRYPT_OK; /* nothing to do */ LTC_ARGCHK(st != NULL); if (st->aadflg) { diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c b/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c index aeecc18..04c5515 100644 --- a/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c @@ -25,7 +25,6 @@ unsigned long padlen; int err; - if (inlen == 0) return CRYPT_OK; /* nothing to do */ LTC_ARGCHK(st != NULL); if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c b/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c index 34da912..ddd0517 100644 --- a/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c @@ -43,6 +43,7 @@ LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; } @@ -51,15 +52,22 @@ } if (direction == CHACHA20POLY1305_ENCRYPT) { if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = chacha20poly1305_done(&st, tag, taglen)) != CRYPT_OK) { goto LBL_ERR; } } else if (direction == CHACHA20POLY1305_DECRYPT) { + unsigned char buf[MAXBLOCKSIZE]; + unsigned long buflen = sizeof(buf); if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = chacha20poly1305_done(&st, buf, &buflen)) != CRYPT_OK) { goto LBL_ERR; } + if (buflen != *taglen || XMEM_NEQ(buf, tag, buflen) != 0) { + err = CRYPT_ERROR; + goto LBL_ERR; + } } else { err = CRYPT_INVALID_ARG; goto LBL_ERR; } - err = chacha20poly1305_done(&st, tag, taglen); LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(&st, sizeof(chacha20poly1305_state)); diff --git a/src/ltc/encauth/gcm/gcm_memory.c b/src/ltc/encauth/gcm/gcm_memory.c index b318f7c..a9c6ac6 100644 --- a/src/ltc/encauth/gcm/gcm_memory.c +++ b/src/ltc/encauth/gcm/gcm_memory.c @@ -93,7 +93,24 @@ if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) { goto LTC_ERR; } - err = gcm_done(gcm, tag, taglen); + if (direction == GCM_ENCRYPT) { + if ((err = gcm_done(gcm, tag, taglen)) != CRYPT_OK) { + goto LTC_ERR; + } + } + else if (direction == GCM_DECRYPT) { + unsigned char buf[MAXBLOCKSIZE]; + unsigned long buflen = sizeof(buf); + if ((err = gcm_done(gcm, buf, &buflen)) != CRYPT_OK) { + goto LTC_ERR; + } + if (buflen != *taglen || XMEM_NEQ(buf, tag, buflen) != 0) { + err = CRYPT_ERROR; + } + } + else { + err = CRYPT_INVALID_ARG; + } LTC_ERR: XFREE(orig); return err; diff --git a/src/ltc/misc/copy_or_zeromem.c b/src/ltc/misc/copy_or_zeromem.c index 1cfd2bd..447b268 100644 --- a/src/ltc/misc/copy_or_zeromem.c +++ b/src/ltc/misc/copy_or_zeromem.c @@ -29,8 +29,7 @@ #endif unsigned char mask = 0xff; /* initialize mask at all ones */ - LTC_ARGCHK(src != NULL); - LTC_ARGCHK(dest != NULL); + if (src == NULL || dest == NULL) return; if (coz != 0) coz = 1; y = 0;