Add dependencies locally
This commit is contained in:
53
deps/libtomcrypt/src/encauth/ccm/ccm_add_aad.c
vendored
Normal file
53
deps/libtomcrypt/src/encauth/ccm/ccm_add_aad.c
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
Add AAD to the CCM state
|
||||
@param ccm The CCM state
|
||||
@param adata The additional authentication data to add to the CCM state
|
||||
@param adatalen The length of the AAD data.
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ccm_add_aad(ccm_state *ccm,
|
||||
const unsigned char *adata, unsigned long adatalen)
|
||||
{
|
||||
unsigned long y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(ccm != NULL);
|
||||
LTC_ARGCHK(adata != NULL);
|
||||
|
||||
if (ccm->aadlen < ccm->current_aadlen + adatalen) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
ccm->current_aadlen += adatalen;
|
||||
|
||||
/* now add the data */
|
||||
for (y = 0; y < adatalen; y++) {
|
||||
if (ccm->x == 16) {
|
||||
/* full block so let's encrypt it */
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ccm->x = 0;
|
||||
}
|
||||
ccm->PAD[ccm->x++] ^= adata[y];
|
||||
}
|
||||
|
||||
/* remainder? */
|
||||
if (ccm->aadlen == ccm->current_aadlen) {
|
||||
if (ccm->x != 0) {
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
ccm->x = 0;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
106
deps/libtomcrypt/src/encauth/ccm/ccm_add_nonce.c
vendored
Normal file
106
deps/libtomcrypt/src/encauth/ccm/ccm_add_nonce.c
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
Add nonce data to the CCM state
|
||||
@param ccm The CCM state
|
||||
@param nonce The nonce data to add
|
||||
@param noncelen The length of the nonce
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ccm_add_nonce(ccm_state *ccm,
|
||||
const unsigned char *nonce, unsigned long noncelen)
|
||||
{
|
||||
unsigned long x, y, len;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(ccm != NULL);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
|
||||
/* increase L to match the nonce len */
|
||||
ccm->noncelen = (noncelen > 13) ? 13 : noncelen;
|
||||
if ((15 - ccm->noncelen) > ccm->L) {
|
||||
ccm->L = 15 - ccm->noncelen;
|
||||
}
|
||||
if (ccm->L > 8) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* decrease noncelen to match L */
|
||||
if ((ccm->noncelen + ccm->L) > 15) {
|
||||
ccm->noncelen = 15 - ccm->L;
|
||||
}
|
||||
|
||||
/* form B_0 == flags | Nonce N | l(m) */
|
||||
x = 0;
|
||||
ccm->PAD[x++] = (unsigned char)(((ccm->aadlen > 0) ? (1<<6) : 0) |
|
||||
(((ccm->taglen - 2)>>1)<<3) |
|
||||
(ccm->L-1));
|
||||
|
||||
/* nonce */
|
||||
for (y = 0; y < 15 - ccm->L; y++) {
|
||||
ccm->PAD[x++] = nonce[y];
|
||||
}
|
||||
|
||||
/* store len */
|
||||
len = ccm->ptlen;
|
||||
|
||||
/* shift len so the upper bytes of len are the contents of the length */
|
||||
for (y = ccm->L; y < 4; y++) {
|
||||
len <<= 8;
|
||||
}
|
||||
|
||||
/* store l(m) (only store 32-bits) */
|
||||
for (y = 0; ccm->L > 4 && (ccm->L-y)>4; y++) {
|
||||
ccm->PAD[x++] = 0;
|
||||
}
|
||||
for (; y < ccm->L; y++) {
|
||||
ccm->PAD[x++] = (unsigned char)((len >> 24) & 255);
|
||||
len <<= 8;
|
||||
}
|
||||
|
||||
/* encrypt PAD */
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* handle header */
|
||||
ccm->x = 0;
|
||||
if (ccm->aadlen > 0) {
|
||||
/* store length */
|
||||
if (ccm->aadlen < ((1UL<<16) - (1UL<<8))) {
|
||||
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255;
|
||||
ccm->PAD[ccm->x++] ^= ccm->aadlen & 255;
|
||||
} else {
|
||||
ccm->PAD[ccm->x++] ^= 0xFF;
|
||||
ccm->PAD[ccm->x++] ^= 0xFE;
|
||||
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>24) & 255;
|
||||
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>16) & 255;
|
||||
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255;
|
||||
ccm->PAD[ccm->x++] ^= ccm->aadlen & 255;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup the ctr counter */
|
||||
x = 0;
|
||||
|
||||
/* flags */
|
||||
ccm->ctr[x++] = (unsigned char)ccm->L-1;
|
||||
|
||||
/* nonce */
|
||||
for (y = 0; y < (16 - (ccm->L+1)); ++y) {
|
||||
ccm->ctr[x++] = nonce[y];
|
||||
}
|
||||
/* offset */
|
||||
while (x < 16) {
|
||||
ccm->ctr[x++] = 0;
|
||||
}
|
||||
|
||||
ccm->CTRlen = 16;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
55
deps/libtomcrypt/src/encauth/ccm/ccm_done.c
vendored
Normal file
55
deps/libtomcrypt/src/encauth/ccm/ccm_done.c
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
Terminate a CCM stream
|
||||
@param ccm The CCM state
|
||||
@param tag [out] The destination for the MAC tag
|
||||
@param taglen [in/out] The length of the MAC tag
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ccm_done(ccm_state *ccm,
|
||||
unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(ccm != NULL);
|
||||
|
||||
/* Check all data have been processed */
|
||||
if (ccm->ptlen != ccm->current_ptlen) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
if (ccm->x != 0) {
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup CTR for the TAG (zero the count) */
|
||||
for (y = 15; y > 15 - ccm->L; y--) {
|
||||
ccm->ctr[y] = 0x00;
|
||||
}
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
cipher_descriptor[ccm->cipher].done(&ccm->K);
|
||||
|
||||
/* store the TAG */
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
tag[x] = ccm->PAD[x] ^ ccm->CTRPAD[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
64
deps/libtomcrypt/src/encauth/ccm/ccm_init.c
vendored
Normal file
64
deps/libtomcrypt/src/encauth/ccm/ccm_init.c
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
Initialize a CCM state
|
||||
@param ccm The CCM state to initialize
|
||||
@param cipher The index of the cipher to use
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key
|
||||
@param ptlen The length of the plain/cipher text that will be processed
|
||||
@param taglen The max length of the MAC tag
|
||||
@param aadlen The length of the AAD
|
||||
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ccm_init(ccm_state *ccm, int cipher,
|
||||
const unsigned char *key, int keylen, int ptlen, int taglen, int aadlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(ccm != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
XMEMSET(ccm, 0, sizeof(ccm_state));
|
||||
|
||||
/* check cipher input */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (cipher_descriptor[cipher].block_length != 16) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
|
||||
/* make sure the taglen is valid */
|
||||
if (taglen < 4 || taglen > 16 || (taglen % 2) == 1 || aadlen < 0 || ptlen < 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
ccm->taglen = taglen;
|
||||
|
||||
/* schedule key */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ccm->cipher = cipher;
|
||||
|
||||
/* let's get the L value */
|
||||
ccm->ptlen = ptlen;
|
||||
ccm->L = 0;
|
||||
while (ptlen) {
|
||||
++ccm->L;
|
||||
ptlen >>= 8;
|
||||
}
|
||||
if (ccm->L <= 1) {
|
||||
ccm->L = 2;
|
||||
}
|
||||
|
||||
ccm->aadlen = aadlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
372
deps/libtomcrypt/src/encauth/ccm/ccm_memory.c
vendored
Normal file
372
deps/libtomcrypt/src/encauth/ccm/ccm_memory.c
vendored
Normal file
@ -0,0 +1,372 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ccm_memory.c
|
||||
CCM support, process a block of memory, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
CCM encrypt/decrypt and produce an authentication tag
|
||||
|
||||
*1 'pt', 'ct' and 'tag' can both be 'in' or 'out', depending on 'direction'
|
||||
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key to use
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param uskey A previously scheduled key [optional can be NULL]
|
||||
@param nonce The session nonce [use once]
|
||||
@param noncelen The length of the nonce
|
||||
@param header The header for the session
|
||||
@param headerlen The length of the header (octets)
|
||||
@param pt [*1] The plaintext
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [*1] The ciphertext
|
||||
@param tag [*1] The destination tag
|
||||
@param taglen The max size and resulting size of the authentication tag
|
||||
@param direction Encrypt or Decrypt direction (0 or 1)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ccm_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction)
|
||||
{
|
||||
unsigned char PAD[16], ctr[16], CTRPAD[16], ptTag[16], b, *pt_real;
|
||||
unsigned char *pt_work = NULL;
|
||||
symmetric_key *skey;
|
||||
int err;
|
||||
unsigned long len, L, x, y, z, CTRlen;
|
||||
|
||||
if (uskey == NULL) {
|
||||
LTC_ARGCHK(key != NULL);
|
||||
}
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
if (headerlen > 0) {
|
||||
LTC_ARGCHK(header != NULL);
|
||||
}
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
pt_real = pt;
|
||||
|
||||
#ifdef LTC_FAST
|
||||
if (16 % sizeof(LTC_FAST_TYPE)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check cipher input */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (cipher_descriptor[cipher].block_length != 16) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
|
||||
/* make sure the taglen is valid */
|
||||
if (*taglen < 4 || *taglen > 16 || (*taglen % 2) == 1 || headerlen > 0x7fffffffu) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* is there an accelerator? */
|
||||
if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
|
||||
return cipher_descriptor[cipher].accel_ccm_memory(
|
||||
key, keylen,
|
||||
uskey,
|
||||
nonce, noncelen,
|
||||
header, headerlen,
|
||||
pt, ptlen,
|
||||
ct,
|
||||
tag, taglen,
|
||||
direction);
|
||||
}
|
||||
|
||||
/* let's get the L value */
|
||||
len = ptlen;
|
||||
L = 0;
|
||||
while (len) {
|
||||
++L;
|
||||
len >>= 8;
|
||||
}
|
||||
if (L <= 1) {
|
||||
L = 2;
|
||||
}
|
||||
|
||||
/* increase L to match the nonce len */
|
||||
noncelen = (noncelen > 13) ? 13 : noncelen;
|
||||
if ((15 - noncelen) > L) {
|
||||
L = 15 - noncelen;
|
||||
}
|
||||
if (L > 8) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* allocate mem for the symmetric key */
|
||||
if (uskey == NULL) {
|
||||
skey = XMALLOC(sizeof(*skey));
|
||||
if (skey == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* initialize the cipher */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
|
||||
XFREE(skey);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
skey = uskey;
|
||||
}
|
||||
|
||||
/* initialize buffer for pt */
|
||||
if (direction == CCM_DECRYPT && ptlen > 0) {
|
||||
pt_work = XMALLOC(ptlen);
|
||||
if (pt_work == NULL) {
|
||||
goto error;
|
||||
}
|
||||
pt = pt_work;
|
||||
}
|
||||
|
||||
/* form B_0 == flags | Nonce N | l(m) */
|
||||
x = 0;
|
||||
PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
|
||||
(((*taglen - 2)>>1)<<3) |
|
||||
(L-1));
|
||||
|
||||
/* nonce */
|
||||
for (y = 0; y < 15 - L; y++) {
|
||||
PAD[x++] = nonce[y];
|
||||
}
|
||||
|
||||
/* store len */
|
||||
len = ptlen;
|
||||
|
||||
/* shift len so the upper bytes of len are the contents of the length */
|
||||
for (y = L; y < 4; y++) {
|
||||
len <<= 8;
|
||||
}
|
||||
|
||||
/* store l(m) (only store 32-bits) */
|
||||
for (y = 0; L > 4 && (L-y)>4; y++) {
|
||||
PAD[x++] = 0;
|
||||
}
|
||||
for (; y < L; y++) {
|
||||
PAD[x++] = (unsigned char)((len >> 24) & 255);
|
||||
len <<= 8;
|
||||
}
|
||||
|
||||
/* encrypt PAD */
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* handle header */
|
||||
if (headerlen > 0) {
|
||||
x = 0;
|
||||
|
||||
/* store length */
|
||||
if (headerlen < ((1UL<<16) - (1UL<<8))) {
|
||||
PAD[x++] ^= (headerlen>>8) & 255;
|
||||
PAD[x++] ^= headerlen & 255;
|
||||
} else {
|
||||
PAD[x++] ^= 0xFF;
|
||||
PAD[x++] ^= 0xFE;
|
||||
PAD[x++] ^= (headerlen>>24) & 255;
|
||||
PAD[x++] ^= (headerlen>>16) & 255;
|
||||
PAD[x++] ^= (headerlen>>8) & 255;
|
||||
PAD[x++] ^= headerlen & 255;
|
||||
}
|
||||
|
||||
/* now add the data */
|
||||
for (y = 0; y < headerlen; y++) {
|
||||
if (x == 16) {
|
||||
/* full block so let's encrypt it */
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
PAD[x++] ^= header[y];
|
||||
}
|
||||
|
||||
/* remainder */
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup the ctr counter */
|
||||
x = 0;
|
||||
|
||||
/* flags */
|
||||
ctr[x++] = (unsigned char)L-1;
|
||||
|
||||
/* nonce */
|
||||
for (y = 0; y < (16 - (L+1)); ++y) {
|
||||
ctr[x++] = nonce[y];
|
||||
}
|
||||
/* offset */
|
||||
while (x < 16) {
|
||||
ctr[x++] = 0;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
CTRlen = 16;
|
||||
|
||||
/* now handle the PT */
|
||||
if (ptlen > 0) {
|
||||
y = 0;
|
||||
#ifdef LTC_FAST
|
||||
if (ptlen & ~15) {
|
||||
if (direction == CCM_ENCRYPT) {
|
||||
for (; y < (ptlen & ~15); y += 16) {
|
||||
/* increment the ctr? */
|
||||
for (z = 15; z > 15-L; z--) {
|
||||
ctr[z] = (ctr[z] + 1) & 255;
|
||||
if (ctr[z]) break;
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* xor the PT against the pad first */
|
||||
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z]));
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z]));
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else { /* direction == CCM_DECRYPT */
|
||||
for (; y < (ptlen & ~15); y += 16) {
|
||||
/* increment the ctr? */
|
||||
for (z = 15; z > 15-L; z--) {
|
||||
ctr[z] = (ctr[z] + 1) & 255;
|
||||
if (ctr[z]) break;
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* xor the PT against the pad last */
|
||||
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z]));
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z]));
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; y < ptlen; y++) {
|
||||
/* increment the ctr? */
|
||||
if (CTRlen == 16) {
|
||||
for (z = 15; z > 15-L; z--) {
|
||||
ctr[z] = (ctr[z] + 1) & 255;
|
||||
if (ctr[z]) break;
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
CTRlen = 0;
|
||||
}
|
||||
|
||||
/* if we encrypt we add the bytes to the MAC first */
|
||||
if (direction == CCM_ENCRYPT) {
|
||||
b = pt[y];
|
||||
ct[y] = b ^ CTRPAD[CTRlen++];
|
||||
} else {
|
||||
b = ct[y] ^ CTRPAD[CTRlen++];
|
||||
pt[y] = b;
|
||||
}
|
||||
|
||||
if (x == 16) {
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
PAD[x++] ^= b;
|
||||
}
|
||||
|
||||
if (x != 0) {
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* setup CTR for the TAG (zero the count) */
|
||||
for (y = 15; y > 15 - L; y--) {
|
||||
ctr[y] = 0x00;
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (skey != uskey) {
|
||||
cipher_descriptor[cipher].done(skey);
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(skey, sizeof(*skey));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (direction == CCM_ENCRYPT) {
|
||||
/* store the TAG */
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
tag[x] = PAD[x] ^ CTRPAD[x];
|
||||
}
|
||||
*taglen = x;
|
||||
} else { /* direction == CCM_DECRYPT */
|
||||
/* decrypt the tag */
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
ptTag[x] = tag[x] ^ CTRPAD[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
/* check validity of the decrypted tag against the computed PAD (in constant time) */
|
||||
/* HACK: the boolean value of XMEM_NEQ becomes either 0 (CRYPT_OK) or 1 (CRYPT_ERR).
|
||||
* there should be a better way of setting the correct error code in constant
|
||||
* time.
|
||||
*/
|
||||
err = XMEM_NEQ(ptTag, PAD, *taglen);
|
||||
|
||||
/* Zero the plaintext if the tag was invalid (in constant time) */
|
||||
if (ptlen > 0) {
|
||||
copy_or_zeromem(pt, pt_real, ptlen, err);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(PAD, sizeof(PAD));
|
||||
zeromem(CTRPAD, sizeof(CTRPAD));
|
||||
if (pt_work != NULL) {
|
||||
zeromem(pt_work, ptlen);
|
||||
}
|
||||
#endif
|
||||
error:
|
||||
if (pt_work) {
|
||||
XFREE(pt_work);
|
||||
}
|
||||
if (skey != uskey) {
|
||||
XFREE(skey);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
78
deps/libtomcrypt/src/encauth/ccm/ccm_process.c
vendored
Normal file
78
deps/libtomcrypt/src/encauth/ccm/ccm_process.c
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
Process plaintext/ciphertext through CCM
|
||||
@param ccm The CCM state
|
||||
@param pt The plaintext
|
||||
@param ptlen The plaintext length (ciphertext length is the same)
|
||||
@param ct The ciphertext
|
||||
@param direction Encrypt or Decrypt mode (CCM_ENCRYPT or CCM_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ccm_process(ccm_state *ccm,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
int direction)
|
||||
{
|
||||
unsigned char z, b;
|
||||
unsigned long y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(ccm != NULL);
|
||||
|
||||
/* Check aad has been correctly added */
|
||||
if (ccm->aadlen != ccm->current_aadlen) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
/* Check we do not process too much data */
|
||||
if (ccm->ptlen < ccm->current_ptlen + ptlen) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
ccm->current_ptlen += ptlen;
|
||||
|
||||
/* now handle the PT */
|
||||
if (ptlen > 0) {
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
|
||||
for (y = 0; y < ptlen; y++) {
|
||||
/* increment the ctr? */
|
||||
if (ccm->CTRlen == 16) {
|
||||
for (z = 15; z > 15-ccm->L; z--) {
|
||||
ccm->ctr[z] = (ccm->ctr[z] + 1) & 255;
|
||||
if (ccm->ctr[z]) break;
|
||||
}
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ccm->CTRlen = 0;
|
||||
}
|
||||
|
||||
/* if we encrypt we add the bytes to the MAC first */
|
||||
if (direction == CCM_ENCRYPT) {
|
||||
b = pt[y];
|
||||
ct[y] = b ^ ccm->CTRPAD[ccm->CTRlen++];
|
||||
} else {
|
||||
b = ct[y] ^ ccm->CTRPAD[ccm->CTRlen++];
|
||||
pt[y] = b;
|
||||
}
|
||||
|
||||
if (ccm->x == 16) {
|
||||
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ccm->x = 0;
|
||||
}
|
||||
ccm->PAD[ccm->x++] ^= b;
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
25
deps/libtomcrypt/src/encauth/ccm/ccm_reset.c
vendored
Normal file
25
deps/libtomcrypt/src/encauth/ccm/ccm_reset.c
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
/**
|
||||
Reset a CCM state to as if you just called ccm_init(). This saves the initialization time.
|
||||
@param ccm The CCM state to reset
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ccm_reset(ccm_state *ccm)
|
||||
{
|
||||
LTC_ARGCHK(ccm != NULL);
|
||||
zeromem(ccm->PAD, sizeof(ccm->PAD));
|
||||
zeromem(ccm->ctr, sizeof(ccm->ctr));
|
||||
zeromem(ccm->CTRPAD, sizeof(ccm->CTRPAD));
|
||||
ccm->CTRlen = 0;
|
||||
ccm->current_ptlen = 0;
|
||||
ccm->current_aadlen = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
274
deps/libtomcrypt/src/encauth/ccm/ccm_test.c
vendored
Normal file
274
deps/libtomcrypt/src/encauth/ccm/ccm_test.c
vendored
Normal file
@ -0,0 +1,274 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ccm_test.c
|
||||
CCM support, process a block of memory, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_CCM_MODE
|
||||
|
||||
int ccm_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
unsigned char key[16];
|
||||
unsigned char nonce[16];
|
||||
int noncelen;
|
||||
unsigned char header[64];
|
||||
int headerlen;
|
||||
unsigned char pt[64];
|
||||
int ptlen;
|
||||
unsigned char ct[64];
|
||||
unsigned char tag[16];
|
||||
unsigned long taglen;
|
||||
} tests[] = {
|
||||
|
||||
/* 13 byte nonce, 8 byte auth, 23 byte pt */
|
||||
{
|
||||
{ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
|
||||
{ 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
|
||||
0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
|
||||
13,
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
|
||||
8,
|
||||
{ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E },
|
||||
23,
|
||||
{ 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
|
||||
0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
|
||||
0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 },
|
||||
{ 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 },
|
||||
8
|
||||
},
|
||||
|
||||
/* 13 byte nonce, 12 byte header, 19 byte pt */
|
||||
{
|
||||
{ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
|
||||
{ 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0,
|
||||
0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
|
||||
13,
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B },
|
||||
12,
|
||||
{ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
|
||||
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
|
||||
0x1C, 0x1D, 0x1E },
|
||||
19,
|
||||
{ 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79,
|
||||
0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91,
|
||||
0xCD, 0xAC, 0x8C },
|
||||
{ 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 },
|
||||
8
|
||||
},
|
||||
|
||||
/* supplied by Brian Gladman */
|
||||
{
|
||||
{ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f },
|
||||
{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 },
|
||||
7,
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
|
||||
8,
|
||||
{ 0x20, 0x21, 0x22, 0x23 },
|
||||
4,
|
||||
{ 0x71, 0x62, 0x01, 0x5b },
|
||||
{ 0x4d, 0xac, 0x25, 0x5d },
|
||||
4
|
||||
},
|
||||
|
||||
{
|
||||
{ 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
|
||||
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f },
|
||||
{ 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5,
|
||||
0x03, 0x97, 0x76, 0xe7, 0x0c },
|
||||
13,
|
||||
{ 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c,
|
||||
0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae,
|
||||
0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 },
|
||||
22,
|
||||
{ 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
|
||||
0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
|
||||
0x7e, 0x78, 0xa0, 0x50 },
|
||||
20,
|
||||
{ 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23,
|
||||
0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c,
|
||||
0x3c, 0x04, 0xd0, 0x19 },
|
||||
{ 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 },
|
||||
8
|
||||
},
|
||||
|
||||
};
|
||||
unsigned long taglen, x, y;
|
||||
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) {
|
||||
idx = find_cipher("rijndael");
|
||||
if (idx == -1) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
for (y = 0; y < 2; y++) {
|
||||
taglen = tests[x].taglen;
|
||||
if (y == 0) {
|
||||
if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = ccm_memory(idx,
|
||||
tests[x].key, 16,
|
||||
&skey,
|
||||
tests[x].nonce, tests[x].noncelen,
|
||||
tests[x].header, tests[x].headerlen,
|
||||
(unsigned char*)tests[x].pt, tests[x].ptlen,
|
||||
buf,
|
||||
tag, &taglen, 0)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
/* run a second time to make sure skey is not touched */
|
||||
if ((err = ccm_memory(idx,
|
||||
tests[x].key, 16,
|
||||
&skey,
|
||||
tests[x].nonce, tests[x].noncelen,
|
||||
tests[x].header, tests[x].headerlen,
|
||||
(unsigned char*)tests[x].pt, tests[x].ptlen,
|
||||
buf,
|
||||
tag, &taglen, 0)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_add_aad(&ccm, tests[x].header, tests[x].headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_process(&ccm, (unsigned char*)tests[x].pt, tests[x].ptlen, buf, CCM_ENCRYPT)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_done(&ccm, tag, &taglen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (compare_testvector(buf, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "CCM encrypt data", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
if (compare_testvector(tag, taglen, tests[x].tag, tests[x].taglen, "CCM encrypt tag", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if (y == 0) {
|
||||
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,
|
||||
tag3, &taglen, 1 )) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_add_aad(&ccm, tests[x].header, tests[x].headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_process(&ccm, buf2, tests[x].ptlen, buf, CCM_DECRYPT)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ccm_done(&ccm, tag2, &taglen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (compare_testvector(buf2, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "CCM decrypt data", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
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 (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 (compare_testvector(buf2, tests[x].ptlen, zero, tests[x].ptlen, "CCM decrypt wrong tag", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
} else {
|
||||
if (compare_testvector(tag2, taglen, tests[x].tag, tests[x].taglen, "CCM decrypt tag", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
if (y == 0) {
|
||||
cipher_descriptor[idx].done(&skey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/452 */
|
||||
{
|
||||
unsigned char key[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
|
||||
unsigned char iv[] = { 0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51 };
|
||||
unsigned char valid_tag[] = { 0x23,0x1a,0x2d,0x8f };
|
||||
unsigned char invalid_tag[] = { 0x23,0x1a,0x2d,0x8f,0x6a };
|
||||
unsigned char msg[] = { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f };
|
||||
unsigned char ct[] = { 0xd3,0xda,0xb1,0xee,0x49,0x4c,0xc2,0x29,0x09,0x9d,0x6c,0xac,0x7d,0xf1,0x4a,0xdd };
|
||||
unsigned char pt[20] = { 0 };
|
||||
|
||||
/* VALID tag */
|
||||
taglen = sizeof(valid_tag);
|
||||
err = ccm_memory(idx, key, sizeof(key), NULL, iv, sizeof(iv), NULL, 0,
|
||||
pt, sizeof(ct), ct, valid_tag, &taglen, CCM_DECRYPT);
|
||||
if ((err != CRYPT_OK) || (XMEMCMP(msg, pt, sizeof(msg)) != 0)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* INVALID tag */
|
||||
taglen = sizeof(invalid_tag);
|
||||
err = ccm_memory(idx, key, sizeof(key), NULL, iv, sizeof(iv), NULL, 0,
|
||||
pt, sizeof(ct), ct, invalid_tag, &taglen, CCM_DECRYPT);
|
||||
if (err == CRYPT_OK) {
|
||||
return CRYPT_FAIL_TESTVECTOR; /* should fail */
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
28
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_add_aad.c
vendored
Normal file
28
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_add_aad.c
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Add AAD to the ChaCha20Poly1305 state
|
||||
@param st The ChaCha20Poly1305 state
|
||||
@param in The additional authentication data to add to the ChaCha20Poly1305 state
|
||||
@param inlen The length of the ChaCha20Poly1305 data.
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (inlen == 0) return CRYPT_OK; /* nothing to do */
|
||||
LTC_ARGCHK(st != NULL);
|
||||
|
||||
if (st->aadflg == 0) return CRYPT_ERROR;
|
||||
if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err;
|
||||
st->aadlen += (ulong64)inlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
38
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_decrypt.c
vendored
Normal file
38
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_decrypt.c
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Decrypt bytes of ciphertext with ChaCha20Poly1305
|
||||
@param st The ChaCha20Poly1305 state
|
||||
@param in The ciphertext
|
||||
@param inlen The length of the input (octets)
|
||||
@param out [out] The plaintext (length inlen)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
unsigned char padzero[16] = { 0 };
|
||||
unsigned long padlen;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
|
||||
if (st->aadflg) {
|
||||
padlen = 16 - (unsigned long)(st->aadlen % 16);
|
||||
if (padlen < 16) {
|
||||
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
|
||||
}
|
||||
st->aadflg = 0; /* no more AAD */
|
||||
}
|
||||
if (st->aadflg) st->aadflg = 0; /* no more AAD */
|
||||
if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err;
|
||||
st->ctlen += (ulong64)inlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
36
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_done.c
vendored
Normal file
36
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_done.c
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Terminate a ChaCha20Poly1305 stream
|
||||
@param st The ChaCha20Poly1305 state
|
||||
@param tag [out] The destination for the MAC tag
|
||||
@param taglen [in/out] The length of the MAC tag
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
unsigned char padzero[16] = { 0 };
|
||||
unsigned long padlen;
|
||||
unsigned char buf[16];
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
|
||||
padlen = 16 - (unsigned long)(st->ctlen % 16);
|
||||
if (padlen < 16) {
|
||||
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
|
||||
}
|
||||
STORE64L(st->aadlen, buf);
|
||||
STORE64L(st->ctlen, buf + 8);
|
||||
if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err;
|
||||
if ((err = poly1305_done(&st->poly, tag, taglen)) != CRYPT_OK) return err;
|
||||
if ((err = chacha_done(&st->chacha)) != CRYPT_OK) return err;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
37
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_encrypt.c
vendored
Normal file
37
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_encrypt.c
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Encrypt bytes of ciphertext with ChaCha20Poly1305
|
||||
@param st The ChaCha20Poly1305 state
|
||||
@param in The plaintext
|
||||
@param inlen The length of the input (octets)
|
||||
@param out [out] The ciphertext (length inlen)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
|
||||
{
|
||||
unsigned char padzero[16] = { 0 };
|
||||
unsigned long padlen;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
|
||||
if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err;
|
||||
if (st->aadflg) {
|
||||
padlen = 16 - (unsigned long)(st->aadlen % 16);
|
||||
if (padlen < 16) {
|
||||
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
|
||||
}
|
||||
st->aadflg = 0; /* no more AAD */
|
||||
}
|
||||
if ((err = poly1305_process(&st->poly, out, inlen)) != CRYPT_OK) return err;
|
||||
st->ctlen += (ulong64)inlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
20
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_init.c
vendored
Normal file
20
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_init.c
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Initialize an ChaCha20Poly1305 context (only the key)
|
||||
@param st [out] The destination of the ChaCha20Poly1305 state
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
return chacha_setup(&st->chacha, key, keylen, 20);
|
||||
}
|
||||
|
||||
#endif
|
72
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_memory.c
vendored
Normal file
72
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_memory.c
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Process an entire GCM packet in one call.
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key
|
||||
@param iv The initialization vector
|
||||
@param ivlen The length of the initialization vector
|
||||
@param aad The additional authentication data (header)
|
||||
@param aadlen The length of the aad
|
||||
@param in The plaintext
|
||||
@param inlen The length of the plaintext (ciphertext length is the same)
|
||||
@param out The ciphertext
|
||||
@param tag [out] The MAC tag
|
||||
@param taglen [in/out] The MAC tag length
|
||||
@param direction Encrypt or Decrypt mode (CHACHA20POLY1305_ENCRYPT or CHACHA20POLY1305_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *iv, unsigned long ivlen,
|
||||
const unsigned char *aad, unsigned long aadlen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction)
|
||||
{
|
||||
chacha20poly1305_state st;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
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; }
|
||||
if (aad && aadlen > 0) {
|
||||
if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
}
|
||||
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;
|
||||
}
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(&st, sizeof(chacha20poly1305_state));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
58
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_setiv.c
vendored
Normal file
58
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_setiv.c
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Set IV + counter data to the ChaCha20Poly1305 state and reset the context
|
||||
@param st The ChaCha20Poly1305 state
|
||||
@param iv The IV data to add
|
||||
@param ivlen The length of the IV (must be 12 or 8)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen)
|
||||
{
|
||||
chacha_state tmp_st;
|
||||
int i, err;
|
||||
unsigned char polykey[32];
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
LTC_ARGCHK(ivlen == 12 || ivlen == 8);
|
||||
|
||||
/* set IV for chacha20 */
|
||||
if (ivlen == 12) {
|
||||
/* IV 96bit */
|
||||
if ((err = chacha_ivctr32(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err;
|
||||
}
|
||||
else {
|
||||
/* IV 64bit */
|
||||
if ((err = chacha_ivctr64(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err;
|
||||
}
|
||||
|
||||
/* copy chacha20 key to temporary state */
|
||||
for(i = 0; i < 12; i++) tmp_st.input[i] = st->chacha.input[i];
|
||||
tmp_st.rounds = 20;
|
||||
/* set IV */
|
||||
if (ivlen == 12) {
|
||||
/* IV 32bit */
|
||||
if ((err = chacha_ivctr32(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err;
|
||||
}
|
||||
else {
|
||||
/* IV 64bit */
|
||||
if ((err = chacha_ivctr64(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err;
|
||||
}
|
||||
/* (re)generate new poly1305 key */
|
||||
if ((err = chacha_keystream(&tmp_st, polykey, 32)) != CRYPT_OK) return err;
|
||||
/* (re)initialise poly1305 */
|
||||
if ((err = poly1305_init(&st->poly, polykey, 32)) != CRYPT_OK) return err;
|
||||
st->ctlen = 0;
|
||||
st->aadlen = 0;
|
||||
st->aadflg = 1;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
30
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c
vendored
Normal file
30
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
/**
|
||||
Set IV + counter data (with RFC7905-magic) to the ChaCha20Poly1305 state and reset the context
|
||||
@param st The ChaCha20Poly1305 state
|
||||
@param iv The IV data to add
|
||||
@param ivlen The length of the IV (must be 12 or 8)
|
||||
@param sequence_number 64bit sequence number which is incorporated into IV as described in RFC7905
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number)
|
||||
{
|
||||
int i;
|
||||
unsigned char combined_iv[12] = { 0 };
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(iv != NULL);
|
||||
LTC_ARGCHK(ivlen == 12);
|
||||
|
||||
STORE64L(sequence_number, combined_iv + 4);
|
||||
for (i = 0; i < 12; i++) combined_iv[i] = iv[i] ^ combined_iv[i];
|
||||
return chacha20poly1305_setiv(st, combined_iv, 12);
|
||||
}
|
||||
|
||||
#endif
|
159
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_test.c
vendored
Normal file
159
deps/libtomcrypt/src/encauth/chachapoly/chacha20poly1305_test.c
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_CHACHA20POLY1305_MODE
|
||||
|
||||
int chacha20poly1305_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
chacha20poly1305_state st1, st2;
|
||||
unsigned char k[] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f };
|
||||
unsigned char i12[] = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 };
|
||||
unsigned char i8[] = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43 };
|
||||
unsigned char aad[] = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
|
||||
unsigned char enc[] = { 0xD3, 0x1A, 0x8D, 0x34, 0x64, 0x8E, 0x60, 0xDB, 0x7B, 0x86, 0xAF, 0xBC, 0x53, 0xEF, 0x7E, 0xC2,
|
||||
0xA4, 0xAD, 0xED, 0x51, 0x29, 0x6E, 0x08, 0xFE, 0xA9, 0xE2, 0xB5, 0xA7, 0x36, 0xEE, 0x62, 0xD6,
|
||||
0x3D, 0xBE, 0xA4, 0x5E, 0x8C, 0xA9, 0x67, 0x12, 0x82, 0xFA, 0xFB, 0x69, 0xDA, 0x92, 0x72, 0x8B,
|
||||
0x1A, 0x71, 0xDE, 0x0A, 0x9E, 0x06, 0x0B, 0x29, 0x05, 0xD6, 0xA5, 0xB6, 0x7E, 0xCD, 0x3B, 0x36,
|
||||
0x92, 0xDD, 0xBD, 0x7F, 0x2D, 0x77, 0x8B, 0x8C, 0x98, 0x03, 0xAE, 0xE3, 0x28, 0x09, 0x1B, 0x58,
|
||||
0xFA, 0xB3, 0x24, 0xE4, 0xFA, 0xD6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8B, 0x48, 0x31, 0xD7, 0xBC,
|
||||
0x3F, 0xF4, 0xDE, 0xF0, 0x8E, 0x4B, 0x7A, 0x9D, 0xE5, 0x76, 0xD2, 0x65, 0x86, 0xCE, 0xC6, 0x4B,
|
||||
0x61, 0x16 };
|
||||
unsigned char tag[] = { 0x1A, 0xE1, 0x0B, 0x59, 0x4F, 0x09, 0xE2, 0x6A, 0x7E, 0x90, 0x2E, 0xCB, 0xD0, 0x60, 0x06, 0x91 };
|
||||
char m[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
|
||||
unsigned long mlen = XSTRLEN(m);
|
||||
unsigned long len;
|
||||
unsigned char rfc7905_pt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
|
||||
unsigned char rfc7905_enc[] = { 0xE4, 0x62, 0x85, 0xB4, 0x29, 0x95, 0x34, 0x96, 0xAB, 0xFB, 0x67, 0xCD, 0xAE, 0xAC, 0x94, 0x1E };
|
||||
unsigned char rfc7905_tag[] = { 0x16, 0x2C, 0x92, 0x48, 0x2A, 0xDB, 0xD3, 0x5D, 0x48, 0xBE, 0xC6, 0xFF, 0x10, 0x9C, 0xBA, 0xE4 };
|
||||
unsigned char ct[1000], pt[1000], emac[16], dmac[16];
|
||||
int err;
|
||||
|
||||
/* encrypt IV 96bit */
|
||||
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_setiv(&st1, i12, sizeof(i12))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
|
||||
/* encrypt piece by piece */
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m, 25, ct)) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 25, 10, ct + 25)) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 35, 35, ct + 35)) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 70, 5, ct + 70)) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 75, 5, ct + 75)) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 80, mlen - 80, ct + 80)) != CRYPT_OK) return err;
|
||||
len = sizeof(emac);
|
||||
if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err;
|
||||
|
||||
if (compare_testvector(ct, mlen, enc, sizeof(enc), "ENC-CT", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(emac, len, tag, sizeof(tag), "ENC-TAG", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* decrypt IV 96bit */
|
||||
if ((err = chacha20poly1305_init(&st2, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_setiv(&st2, i12, sizeof(i12))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_add_aad(&st2, aad, sizeof(aad))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_decrypt(&st2, ct, 21, pt)) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_decrypt(&st2, ct + 21, mlen - 21, pt + 21)) != CRYPT_OK) return err;
|
||||
len = sizeof(dmac);
|
||||
if ((err = chacha20poly1305_done(&st2, dmac, &len)) != CRYPT_OK) return err;
|
||||
|
||||
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(dmac, len, tag, sizeof(tag), "DEC-TAG", 4) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* chacha20poly1305_memory - encrypt */
|
||||
len = sizeof(emac);
|
||||
if ((err = chacha20poly1305_memory(k, sizeof(k), i12, sizeof(i12), aad, sizeof(aad), (unsigned char *)m,
|
||||
mlen, ct, emac, &len, CHACHA20POLY1305_ENCRYPT)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(ct, mlen, enc, sizeof(enc), "ENC-CT2", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(emac, len, tag, sizeof(tag), "ENC-TAG2", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* chacha20poly1305_memory - decrypt */
|
||||
len = sizeof(dmac);
|
||||
XMEMCPY(dmac, tag, sizeof(tag));
|
||||
if ((err = chacha20poly1305_memory(k, sizeof(k), i12, sizeof(i12), aad, sizeof(aad),
|
||||
ct, mlen, pt, dmac, &len, CHACHA20POLY1305_DECRYPT)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT2", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* encrypt - rfc7905 */
|
||||
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_setiv_rfc7905(&st1, i12, sizeof(i12), CONST64(0x1122334455667788))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, rfc7905_pt, 16, ct)) != CRYPT_OK) return err;
|
||||
len = sizeof(emac);
|
||||
if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err;
|
||||
|
||||
if (compare_testvector(ct, 16, rfc7905_enc, 16, "ENC-CT3", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(emac, len, rfc7905_tag, 16, "ENC-TAG3", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* decrypt - rfc7905 */
|
||||
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_setiv_rfc7905(&st1, i12, sizeof(i12), CONST64(0x1122334455667788))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_decrypt(&st1, ct, 16, pt)) != CRYPT_OK) return err;
|
||||
len = sizeof(dmac);
|
||||
if ((err = chacha20poly1305_done(&st1, dmac, &len)) != CRYPT_OK) return err;
|
||||
|
||||
if (compare_testvector(pt, 16, rfc7905_pt, 16, "DEC-CT3", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(dmac, len, rfc7905_tag, 16, "DEC-TAG3", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* encrypt IV 64bit */
|
||||
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_setiv(&st1, i8, sizeof(i8))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m, mlen, ct)) != CRYPT_OK) return err;
|
||||
len = sizeof(emac);
|
||||
if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err;
|
||||
|
||||
/* decrypt IV 64bit */
|
||||
if ((err = chacha20poly1305_init(&st2, k, sizeof(k))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_setiv(&st2, i8, sizeof(i8))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_add_aad(&st2, aad, sizeof(aad))) != CRYPT_OK) return err;
|
||||
if ((err = chacha20poly1305_decrypt(&st2, ct, mlen, pt)) != CRYPT_OK) return err;
|
||||
len = sizeof(dmac);
|
||||
if ((err = chacha20poly1305_done(&st2, dmac, &len)) != CRYPT_OK) return err;
|
||||
|
||||
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT4", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(dmac, len, emac, len, "DEC-TAG4", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/451 */
|
||||
{
|
||||
unsigned char key[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,
|
||||
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
|
||||
unsigned char iv[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b };
|
||||
unsigned char valid_tag[] = { 0xa3,0xe3,0xfd,0xf9,0xfb,0xa6,0x86,0x1b,0x5a,0xd2,0x60,0x7f,0x40,0xb7,0xf4,0x47 };
|
||||
unsigned char invalid_tag[] = { 0xa2,0xe3,0xfd,0xf9,0xfb,0xa6,0x86,0x1b,0x5a,0xd2,0x60,0x7f,0x40,0xb7,0xf4,0x47 };
|
||||
unsigned char waad[] = { 0x61,0x61,0x64 };
|
||||
unsigned char wct[] = { 0x00 };
|
||||
unsigned char wpt[20] = { 0 };
|
||||
unsigned char wtag[20] = { 0 };
|
||||
unsigned long taglen;
|
||||
|
||||
/* encrypt */
|
||||
taglen = sizeof(wtag);
|
||||
err = chacha20poly1305_memory(key, sizeof(key), iv, sizeof(iv), waad, sizeof(waad),
|
||||
wpt, 0, wct, wtag, &taglen, CHACHA20POLY1305_ENCRYPT);
|
||||
if (err != CRYPT_OK) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(wtag, taglen, valid_tag, sizeof(valid_tag), "WYCH", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* VALID tag */
|
||||
taglen = sizeof(valid_tag);
|
||||
err = chacha20poly1305_memory(key, sizeof(key), iv, sizeof(iv), waad, sizeof(waad),
|
||||
wpt, 0, wct, valid_tag, &taglen, CHACHA20POLY1305_DECRYPT);
|
||||
if (err != CRYPT_OK) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
/* INVALID tag */
|
||||
taglen = sizeof(invalid_tag);
|
||||
err = chacha20poly1305_memory(key, sizeof(key), iv, sizeof(iv), waad, sizeof(waad),
|
||||
wpt, 0, wct, invalid_tag, &taglen, CHACHA20POLY1305_DECRYPT);
|
||||
if (err == CRYPT_OK) {
|
||||
return CRYPT_FAIL_TESTVECTOR; /* should fail */
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
26
deps/libtomcrypt/src/encauth/eax/eax_addheader.c
vendored
Normal file
26
deps/libtomcrypt/src/encauth/eax/eax_addheader.c
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
/**
|
||||
@file eax_addheader.c
|
||||
EAX implementation, add meta-data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
add header (metadata) to the stream
|
||||
@param eax The current EAX state
|
||||
@param header The header (meta-data) data you wish to add to the state
|
||||
@param length The length of the header data
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int eax_addheader(eax_state *eax, const unsigned char *header,
|
||||
unsigned long length)
|
||||
{
|
||||
LTC_ARGCHK(eax != NULL);
|
||||
LTC_ARGCHK(header != NULL);
|
||||
return omac_process(&eax->headeromac, header, length);
|
||||
}
|
||||
|
||||
#endif
|
38
deps/libtomcrypt/src/encauth/eax/eax_decrypt.c
vendored
Normal file
38
deps/libtomcrypt/src/encauth/eax/eax_decrypt.c
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_decrypt.c
|
||||
EAX implementation, decrypt block, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
Decrypt data with the EAX protocol
|
||||
@param eax The EAX state
|
||||
@param ct The ciphertext
|
||||
@param pt [out] The plaintext
|
||||
@param length The length (octets) of the ciphertext
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt,
|
||||
unsigned long length)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(eax != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
|
||||
/* omac ciphertext */
|
||||
if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* decrypt */
|
||||
return ctr_decrypt(ct, pt, length, &eax->ctr);
|
||||
}
|
||||
|
||||
#endif
|
99
deps/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c
vendored
Normal file
99
deps/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_decrypt_verify_memory.c
|
||||
EAX implementation, decrypt block of memory, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
Decrypt a block of memory and verify the provided MAC tag with EAX
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key
|
||||
@param keylen The length of the key (octets)
|
||||
@param nonce The nonce data (use once) for the session
|
||||
@param noncelen The length of the nonce data.
|
||||
@param header The session header data
|
||||
@param headerlen The length of the header (octets)
|
||||
@param ct The ciphertext
|
||||
@param ctlen The length of the ciphertext (octets)
|
||||
@param pt [out] The plaintext
|
||||
@param tag The authentication tag provided by the encoder
|
||||
@param taglen [in/out] The length of the tag (octets)
|
||||
@param stat [out] The result of the decryption (1==valid tag, 0==invalid)
|
||||
@return CRYPT_OK if successful regardless of the resulting tag comparison
|
||||
*/
|
||||
int eax_decrypt_verify_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tag, unsigned long taglen,
|
||||
int *stat)
|
||||
{
|
||||
int err;
|
||||
eax_state *eax;
|
||||
unsigned char *buf;
|
||||
unsigned long buflen;
|
||||
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
|
||||
/* default to zero */
|
||||
*stat = 0;
|
||||
|
||||
/* limit taglen */
|
||||
taglen = MIN(taglen, MAXBLOCKSIZE);
|
||||
|
||||
/* allocate ram */
|
||||
buf = XMALLOC(taglen);
|
||||
eax = XMALLOC(sizeof(*eax));
|
||||
if (eax == NULL || buf == NULL) {
|
||||
if (eax != NULL) {
|
||||
XFREE(eax);
|
||||
}
|
||||
if (buf != NULL) {
|
||||
XFREE(buf);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
buflen = taglen;
|
||||
if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* compare tags */
|
||||
if (buflen >= taglen && XMEM_NEQ(buf, tag, taglen) == 0) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(buf, taglen);
|
||||
zeromem(eax, sizeof(*eax));
|
||||
#endif
|
||||
|
||||
XFREE(eax);
|
||||
XFREE(buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
82
deps/libtomcrypt/src/encauth/eax/eax_done.c
vendored
Normal file
82
deps/libtomcrypt/src/encauth/eax/eax_done.c
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_done.c
|
||||
EAX implementation, terminate session, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
Terminate an EAX session and get the tag.
|
||||
@param eax The EAX state
|
||||
@param tag [out] The destination of the authentication tag
|
||||
@param taglen [in/out] The max length and resulting length of the authentication tag
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
int err;
|
||||
unsigned char *headermac, *ctmac;
|
||||
unsigned long x, len;
|
||||
|
||||
LTC_ARGCHK(eax != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
/* allocate ram */
|
||||
headermac = XMALLOC(MAXBLOCKSIZE);
|
||||
ctmac = XMALLOC(MAXBLOCKSIZE);
|
||||
|
||||
if (headermac == NULL || ctmac == NULL) {
|
||||
if (headermac != NULL) {
|
||||
XFREE(headermac);
|
||||
}
|
||||
if (ctmac != NULL) {
|
||||
XFREE(ctmac);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* finish ctomac */
|
||||
len = MAXBLOCKSIZE;
|
||||
if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* finish headeromac */
|
||||
|
||||
/* note we specifically don't reset len so the two lens are minimal */
|
||||
|
||||
if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* terminate the CTR chain */
|
||||
if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* compute N xor H xor C */
|
||||
for (x = 0; x < len && x < *taglen; x++) {
|
||||
tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(ctmac, MAXBLOCKSIZE);
|
||||
zeromem(headermac, MAXBLOCKSIZE);
|
||||
zeromem(eax, sizeof(*eax));
|
||||
#endif
|
||||
|
||||
XFREE(ctmac);
|
||||
XFREE(headermac);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
39
deps/libtomcrypt/src/encauth/eax/eax_encrypt.c
vendored
Normal file
39
deps/libtomcrypt/src/encauth/eax/eax_encrypt.c
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_encrypt.c
|
||||
EAX implementation, encrypt block by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
Encrypt with EAX a block of data.
|
||||
@param eax The EAX state
|
||||
@param pt The plaintext to encrypt
|
||||
@param ct [out] The ciphertext as encrypted
|
||||
@param length The length of the plaintext (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct,
|
||||
unsigned long length)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(eax != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
|
||||
/* encrypt */
|
||||
if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* omac ciphertext */
|
||||
return omac_process(&eax->ctomac, ct, length);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
70
deps/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c
vendored
Normal file
70
deps/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_encrypt_authenticate_memory.c
|
||||
EAX implementation, encrypt a block of memory, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
EAX encrypt and produce an authentication tag
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key to use
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce [use once]
|
||||
@param noncelen The length of the nonce
|
||||
@param header The header for the session
|
||||
@param headerlen The length of the header (octets)
|
||||
@param pt The plaintext
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [out] The ciphertext
|
||||
@param tag [out] The destination tag
|
||||
@param taglen [in/out] The max size and resulting size of the authentication tag
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int eax_encrypt_authenticate_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
int err;
|
||||
eax_state *eax;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
eax = XMALLOC(sizeof(*eax));
|
||||
|
||||
if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(eax, sizeof(*eax));
|
||||
#endif
|
||||
|
||||
XFREE(eax);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
132
deps/libtomcrypt/src/encauth/eax/eax_init.c
vendored
Normal file
132
deps/libtomcrypt/src/encauth/eax/eax_init.c
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_init.c
|
||||
EAX implementation, initialized EAX state, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
Initialized an EAX state
|
||||
@param eax [out] The EAX state to initialize
|
||||
@param cipher The index of the desired cipher
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The use-once nonce for the session
|
||||
@param noncelen The length of the nonce (octets)
|
||||
@param header The header for the EAX state
|
||||
@param headerlen The header length (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int eax_init(eax_state *eax, int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen)
|
||||
{
|
||||
unsigned char *buf;
|
||||
int err, blklen;
|
||||
omac_state *omac;
|
||||
unsigned long len;
|
||||
|
||||
|
||||
LTC_ARGCHK(eax != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
if (headerlen > 0) {
|
||||
LTC_ARGCHK(header != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
blklen = cipher_descriptor[cipher].block_length;
|
||||
|
||||
/* allocate ram */
|
||||
buf = XMALLOC(MAXBLOCKSIZE);
|
||||
omac = XMALLOC(sizeof(*omac));
|
||||
|
||||
if (buf == NULL || omac == NULL) {
|
||||
if (buf != NULL) {
|
||||
XFREE(buf);
|
||||
}
|
||||
if (omac != NULL) {
|
||||
XFREE(omac);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* N = LTC_OMAC_0K(nonce) */
|
||||
zeromem(buf, MAXBLOCKSIZE);
|
||||
if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* omac the [0]_n */
|
||||
if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
/* omac the nonce */
|
||||
if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
/* store result */
|
||||
len = sizeof(eax->N);
|
||||
if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* H = LTC_OMAC_1K(header) */
|
||||
zeromem(buf, MAXBLOCKSIZE);
|
||||
buf[blklen - 1] = 1;
|
||||
|
||||
if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* omac the [1]_n */
|
||||
if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
/* omac the header */
|
||||
if (headerlen != 0) {
|
||||
if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/* note we don't finish the headeromac, this allows us to add more header later */
|
||||
|
||||
/* setup the CTR mode */
|
||||
if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* setup the LTC_OMAC for the ciphertext */
|
||||
if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* omac [2]_n */
|
||||
zeromem(buf, MAXBLOCKSIZE);
|
||||
buf[blklen-1] = 2;
|
||||
if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(buf, MAXBLOCKSIZE);
|
||||
zeromem(omac, sizeof(*omac));
|
||||
#endif
|
||||
|
||||
XFREE(omac);
|
||||
XFREE(buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
249
deps/libtomcrypt/src/encauth/eax/eax_test.c
vendored
Normal file
249
deps/libtomcrypt/src/encauth/eax/eax_test.c
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file eax_test.c
|
||||
EAX implementation, self-test, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_EAX_MODE
|
||||
|
||||
/**
|
||||
Test the EAX implementation
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
|
||||
*/
|
||||
int eax_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
int keylen,
|
||||
noncelen,
|
||||
headerlen,
|
||||
msglen;
|
||||
|
||||
unsigned char key[MAXBLOCKSIZE],
|
||||
nonce[MAXBLOCKSIZE],
|
||||
header[MAXBLOCKSIZE],
|
||||
plaintext[MAXBLOCKSIZE],
|
||||
ciphertext[MAXBLOCKSIZE],
|
||||
tag[MAXBLOCKSIZE];
|
||||
} tests[] = {
|
||||
|
||||
/* NULL message */
|
||||
{
|
||||
16, 0, 0, 0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0 },
|
||||
/* header */
|
||||
{ 0 },
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5,
|
||||
0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff }
|
||||
},
|
||||
|
||||
/* test with nonce */
|
||||
{
|
||||
16, 16, 0, 0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* header */
|
||||
{ 0 },
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb,
|
||||
0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec }
|
||||
},
|
||||
|
||||
/* test with header [no nonce] */
|
||||
{
|
||||
16, 0, 16, 0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0 },
|
||||
/* header */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0,
|
||||
0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff }
|
||||
},
|
||||
|
||||
/* test with header + nonce + plaintext */
|
||||
{
|
||||
16, 16, 16, 32,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* header */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* plaintext */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
|
||||
/* ciphertext */
|
||||
{ 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b,
|
||||
0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78,
|
||||
0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f,
|
||||
0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc },
|
||||
/* tag */
|
||||
{ 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e,
|
||||
0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 }
|
||||
},
|
||||
|
||||
/* test with header + nonce + plaintext [not even sizes!] */
|
||||
{
|
||||
16, 15, 14, 29,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e },
|
||||
/* header */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d },
|
||||
/* plaintext */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c },
|
||||
/* ciphertext */
|
||||
{ 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59,
|
||||
0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8,
|
||||
0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c,
|
||||
0x8a, 0x24, 0xdb, 0x86, 0x8b },
|
||||
/* tag */
|
||||
{ 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
|
||||
0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda }
|
||||
},
|
||||
|
||||
/* Vectors from Brian Gladman */
|
||||
|
||||
{
|
||||
16, 16, 8, 0,
|
||||
/* key */
|
||||
{ 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f,
|
||||
0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 },
|
||||
/* nonce */
|
||||
{ 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07,
|
||||
0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 },
|
||||
/* header */
|
||||
{ 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b },
|
||||
/* PT */
|
||||
{ 0x00 },
|
||||
/* CT */
|
||||
{ 0x00 },
|
||||
/* tag */
|
||||
{ 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b,
|
||||
0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 }
|
||||
},
|
||||
|
||||
{
|
||||
16, 16, 8, 2,
|
||||
/* key */
|
||||
{ 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b,
|
||||
0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 },
|
||||
/* nonce */
|
||||
{ 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84,
|
||||
0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd },
|
||||
/* header */
|
||||
{ 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa },
|
||||
/* PT */
|
||||
{ 0xf7, 0xfb },
|
||||
/* CT */
|
||||
{ 0x19, 0xdd },
|
||||
/* tag */
|
||||
{ 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda,
|
||||
0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 }
|
||||
},
|
||||
|
||||
{
|
||||
16, 16, 8, 5,
|
||||
/* key */
|
||||
{ 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7,
|
||||
0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 },
|
||||
/* nonce */
|
||||
{ 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84,
|
||||
0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e },
|
||||
/* header */
|
||||
{ 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 },
|
||||
/* PT */
|
||||
{ 0x1a, 0x47, 0xcb, 0x49, 0x33 },
|
||||
/* CT */
|
||||
{ 0xd8, 0x51, 0xd5, 0xba, 0xe0 },
|
||||
/* Tag */
|
||||
{ 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19,
|
||||
0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 }
|
||||
}
|
||||
|
||||
};
|
||||
int err, x, idx, res;
|
||||
unsigned long len;
|
||||
unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE];
|
||||
|
||||
/* AES can be under rijndael or aes... try to find it */
|
||||
if ((idx = find_cipher("aes")) == -1) {
|
||||
if ((idx = find_cipher("rijndael")) == -1) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
len = sizeof(outtag);
|
||||
if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen,
|
||||
tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
|
||||
tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (compare_testvector(outtag, len, tests[x].tag, len, "EAX Tag", x) ||
|
||||
compare_testvector(outct, tests[x].msglen, tests[x].ciphertext, tests[x].msglen, "EAX CT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* test decrypt */
|
||||
if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen,
|
||||
tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
|
||||
outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || compare_testvector(outct, tests[x].msglen, tests[x].plaintext, tests[x].msglen, "EAX", x)) {
|
||||
#ifdef LTC_TEST_DBG
|
||||
printf("\n\nEAX: Failure-decrypt - res = %d\n", res);
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif /* LTC_TEST */
|
||||
}
|
||||
|
||||
#endif /* LTC_EAX_MODE */
|
114
deps/libtomcrypt/src/encauth/gcm/gcm_add_aad.c
vendored
Normal file
114
deps/libtomcrypt/src/encauth/gcm/gcm_add_aad.c
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_add_aad.c
|
||||
GCM implementation, Add AAD data to the stream, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Add AAD to the GCM state
|
||||
@param gcm The GCM state
|
||||
@param adata The additional authentication data to add to the GCM state
|
||||
@param adatalen The length of the AAD data.
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_add_aad(gcm_state *gcm,
|
||||
const unsigned char *adata, unsigned long adatalen)
|
||||
{
|
||||
unsigned long x;
|
||||
int err;
|
||||
#ifdef LTC_FAST
|
||||
unsigned long y;
|
||||
#endif
|
||||
|
||||
LTC_ARGCHK(gcm != NULL);
|
||||
if (adatalen > 0) {
|
||||
LTC_ARGCHK(adata != NULL);
|
||||
}
|
||||
|
||||
if (gcm->buflen > 16 || gcm->buflen < 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* in IV mode? */
|
||||
if (gcm->mode == LTC_GCM_MODE_IV) {
|
||||
/* IV length must be > 0 */
|
||||
if (gcm->buflen == 0 && gcm->totlen == 0) return CRYPT_ERROR;
|
||||
/* let's process the IV */
|
||||
if (gcm->ivmode || gcm->buflen != 12) {
|
||||
for (x = 0; x < (unsigned long)gcm->buflen; x++) {
|
||||
gcm->X[x] ^= gcm->buf[x];
|
||||
}
|
||||
if (gcm->buflen) {
|
||||
gcm->totlen += gcm->buflen * CONST64(8);
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
}
|
||||
|
||||
/* mix in the length */
|
||||
zeromem(gcm->buf, 8);
|
||||
STORE64H(gcm->totlen, gcm->buf+8);
|
||||
for (x = 0; x < 16; x++) {
|
||||
gcm->X[x] ^= gcm->buf[x];
|
||||
}
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
|
||||
/* copy counter out */
|
||||
XMEMCPY(gcm->Y, gcm->X, 16);
|
||||
zeromem(gcm->X, 16);
|
||||
} else {
|
||||
XMEMCPY(gcm->Y, gcm->buf, 12);
|
||||
gcm->Y[12] = 0;
|
||||
gcm->Y[13] = 0;
|
||||
gcm->Y[14] = 0;
|
||||
gcm->Y[15] = 1;
|
||||
}
|
||||
XMEMCPY(gcm->Y_0, gcm->Y, 16);
|
||||
zeromem(gcm->buf, 16);
|
||||
gcm->buflen = 0;
|
||||
gcm->totlen = 0;
|
||||
gcm->mode = LTC_GCM_MODE_AAD;
|
||||
}
|
||||
|
||||
if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
#ifdef LTC_FAST
|
||||
if (gcm->buflen == 0 && adatalen > 15) {
|
||||
for (x = 0; x < (adatalen & ~15); x += 16) {
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&adata[x + y]));
|
||||
}
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
gcm->totlen += 128;
|
||||
}
|
||||
adata += x;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* start adding AAD data to the state */
|
||||
for (; x < adatalen; x++) {
|
||||
gcm->X[gcm->buflen++] ^= *adata++;
|
||||
|
||||
if (gcm->buflen == 16) {
|
||||
/* GF mult it */
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
gcm->buflen = 0;
|
||||
gcm->totlen += 128;
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
#endif
|
||||
|
82
deps/libtomcrypt/src/encauth/gcm/gcm_add_iv.c
vendored
Normal file
82
deps/libtomcrypt/src/encauth/gcm/gcm_add_iv.c
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_add_iv.c
|
||||
GCM implementation, add IV data to the state, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Add IV data to the GCM state
|
||||
@param gcm The GCM state
|
||||
@param IV The initial value data to add
|
||||
@param IVlen The length of the IV
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_add_iv(gcm_state *gcm,
|
||||
const unsigned char *IV, unsigned long IVlen)
|
||||
{
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(gcm != NULL);
|
||||
if (IVlen > 0) {
|
||||
LTC_ARGCHK(IV != NULL);
|
||||
}
|
||||
|
||||
/* must be in IV mode */
|
||||
if (gcm->mode != LTC_GCM_MODE_IV) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (gcm->buflen >= 16 || gcm->buflen < 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* trip the ivmode flag */
|
||||
if (IVlen + gcm->buflen > 12) {
|
||||
gcm->ivmode |= 1;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
#ifdef LTC_FAST
|
||||
if (gcm->buflen == 0) {
|
||||
for (x = 0; x < (IVlen & ~15); x += 16) {
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&IV[x + y]));
|
||||
}
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
gcm->totlen += 128;
|
||||
}
|
||||
IV += x;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* start adding IV data to the state */
|
||||
for (; x < IVlen; x++) {
|
||||
gcm->buf[gcm->buflen++] = *IV++;
|
||||
|
||||
if (gcm->buflen == 16) {
|
||||
/* GF mult it */
|
||||
for (y = 0; y < 16; y++) {
|
||||
gcm->X[y] ^= gcm->buf[y];
|
||||
}
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
gcm->buflen = 0;
|
||||
gcm->totlen += 128;
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
80
deps/libtomcrypt/src/encauth/gcm/gcm_done.c
vendored
Normal file
80
deps/libtomcrypt/src/encauth/gcm/gcm_done.c
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_done.c
|
||||
GCM implementation, Terminate the stream, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Terminate a GCM stream
|
||||
@param gcm The GCM state
|
||||
@param tag [out] The destination for the MAC tag
|
||||
@param taglen [in/out] The length of the MAC tag
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_done(gcm_state *gcm,
|
||||
unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
unsigned long x;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(gcm != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
if (gcm->buflen > 16 || gcm->buflen < 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (gcm->mode == LTC_GCM_MODE_IV) {
|
||||
/* let's process the IV */
|
||||
if ((err = gcm_add_aad(gcm, NULL, 0)) != CRYPT_OK) return err;
|
||||
}
|
||||
|
||||
if (gcm->mode == LTC_GCM_MODE_AAD) {
|
||||
/* let's process the AAD */
|
||||
if ((err = gcm_process(gcm, NULL, 0, NULL, 0)) != CRYPT_OK) return err;
|
||||
}
|
||||
|
||||
if (gcm->mode != LTC_GCM_MODE_TEXT) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* handle remaining ciphertext */
|
||||
if (gcm->buflen) {
|
||||
gcm->pttotlen += gcm->buflen * CONST64(8);
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
}
|
||||
|
||||
/* length */
|
||||
STORE64H(gcm->totlen, gcm->buf);
|
||||
STORE64H(gcm->pttotlen, gcm->buf+8);
|
||||
for (x = 0; x < 16; x++) {
|
||||
gcm->X[x] ^= gcm->buf[x];
|
||||
}
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
|
||||
/* encrypt original counter */
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
tag[x] = gcm->buf[x] ^ gcm->X[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
cipher_descriptor[gcm->cipher].done(&gcm->K);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
209
deps/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c
vendored
Normal file
209
deps/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_gf_mult.c
|
||||
GCM implementation, do the GF mult, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || (defined(LTC_GCM_MODE) && defined(LTC_FAST))
|
||||
|
||||
/* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the
|
||||
* lower 16 bits are not zero'ed I removed the upper 14 bytes */
|
||||
const unsigned char gcm_shift_table[256*2] = {
|
||||
0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e,
|
||||
0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e,
|
||||
0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e,
|
||||
0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e,
|
||||
0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e,
|
||||
0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e,
|
||||
0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e,
|
||||
0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e,
|
||||
0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce,
|
||||
0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde,
|
||||
0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee,
|
||||
0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe,
|
||||
0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e,
|
||||
0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e,
|
||||
0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae,
|
||||
0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe,
|
||||
0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e,
|
||||
0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e,
|
||||
0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e,
|
||||
0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e,
|
||||
0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e,
|
||||
0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e,
|
||||
0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e,
|
||||
0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e,
|
||||
0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce,
|
||||
0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde,
|
||||
0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee,
|
||||
0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe,
|
||||
0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e,
|
||||
0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e,
|
||||
0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae,
|
||||
0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(LTC_GCM_MODE) || defined(LRW_MODE)
|
||||
|
||||
#ifndef LTC_FAST
|
||||
/* right shift */
|
||||
static void s_gcm_rightshift(unsigned char *a)
|
||||
{
|
||||
int x;
|
||||
for (x = 15; x > 0; x--) {
|
||||
a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80);
|
||||
}
|
||||
a[0] >>= 1;
|
||||
}
|
||||
|
||||
/* c = b*a */
|
||||
static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||
static const unsigned char poly[] = { 0x00, 0xE1 };
|
||||
|
||||
|
||||
/**
|
||||
GCM GF multiplier (internal use only) bitserial
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@param c Destination for a * b
|
||||
*/
|
||||
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
|
||||
{
|
||||
unsigned char Z[16], V[16];
|
||||
unsigned char x, y, z;
|
||||
|
||||
zeromem(Z, 16);
|
||||
XMEMCPY(V, a, 16);
|
||||
for (x = 0; x < 128; x++) {
|
||||
if (b[x>>3] & mask[x&7]) {
|
||||
for (y = 0; y < 16; y++) {
|
||||
Z[y] ^= V[y];
|
||||
}
|
||||
}
|
||||
z = V[15] & 0x01;
|
||||
s_gcm_rightshift(V);
|
||||
V[0] ^= poly[z];
|
||||
}
|
||||
XMEMCPY(c, Z, 16);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* map normal numbers to "ieee" way ... e.g. bit reversed */
|
||||
#define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) )
|
||||
|
||||
#define BPD (sizeof(LTC_FAST_TYPE) * 8)
|
||||
#define WPV (1 + (16 / sizeof(LTC_FAST_TYPE)))
|
||||
|
||||
/**
|
||||
GCM GF multiplier (internal use only) word oriented
|
||||
@param a First value
|
||||
@param b Second value
|
||||
@param c Destination for a * b
|
||||
*/
|
||||
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
|
||||
{
|
||||
int i, j, k, u;
|
||||
LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z;
|
||||
unsigned char pTmp[32];
|
||||
|
||||
/* create simple tables */
|
||||
zeromem(B[0], sizeof(B[0]));
|
||||
zeromem(B[M(1)], sizeof(B[M(1)]));
|
||||
|
||||
#ifdef ENDIAN_32BITWORD
|
||||
for (i = 0; i < 4; i++) {
|
||||
LOAD32H(B[M(1)][i], a + (i<<2));
|
||||
LOAD32L(pB[i], b + (i<<2));
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < 2; i++) {
|
||||
LOAD64H(B[M(1)][i], a + (i<<3));
|
||||
LOAD64L(pB[i], b + (i<<3));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* now create 2, 4 and 8 */
|
||||
B[M(2)][0] = B[M(1)][0] >> 1;
|
||||
B[M(4)][0] = B[M(1)][0] >> 2;
|
||||
B[M(8)][0] = B[M(1)][0] >> 3;
|
||||
for (i = 1; i < (int)WPV; i++) {
|
||||
B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1);
|
||||
B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2);
|
||||
B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3);
|
||||
}
|
||||
|
||||
/* now all values with two bits which are 3, 5, 6, 9, 10, 12 */
|
||||
for (i = 0; i < (int)WPV; i++) {
|
||||
B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i];
|
||||
B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i];
|
||||
B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i];
|
||||
B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i];
|
||||
B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i];
|
||||
B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i];
|
||||
|
||||
/* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */
|
||||
B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i];
|
||||
B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i];
|
||||
B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i];
|
||||
B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i];
|
||||
B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i];
|
||||
}
|
||||
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
|
||||
/* compute product four bits of each word at a time */
|
||||
/* for each nibble */
|
||||
for (i = (BPD/4)-1; i >= 0; i--) {
|
||||
/* for each word */
|
||||
for (j = 0; j < (int)(WPV-1); j++) {
|
||||
/* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */
|
||||
u = (pB[j] >> ((i^1)<<2)) & 15;
|
||||
|
||||
/* add offset by the word count the table looked up value to the result */
|
||||
for (k = 0; k < (int)WPV; k++) {
|
||||
tmp[k+j] ^= B[u][k];
|
||||
}
|
||||
}
|
||||
/* shift result up by 4 bits */
|
||||
if (i != 0) {
|
||||
for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) {
|
||||
zz = tmp[j] << (BPD-4);
|
||||
tmp[j] = (tmp[j] >> 4) | z;
|
||||
z = zz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* store product */
|
||||
#ifdef ENDIAN_32BITWORD
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE32H(tmp[i], pTmp + (i<<2));
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE64H(tmp[i], pTmp + (i<<3));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */
|
||||
for (i = 31; i >= 16; i--) {
|
||||
pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)];
|
||||
pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1];
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
c[i] = pTmp[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
95
deps/libtomcrypt/src/encauth/gcm/gcm_init.c
vendored
Normal file
95
deps/libtomcrypt/src/encauth/gcm/gcm_init.c
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_init.c
|
||||
GCM implementation, initialize state, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Initialize a GCM state
|
||||
@param gcm The GCM state to initialize
|
||||
@param cipher The index of the cipher to use
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_init(gcm_state *gcm, int cipher,
|
||||
const unsigned char *key, int keylen)
|
||||
{
|
||||
int err;
|
||||
unsigned char B[16];
|
||||
#ifdef LTC_GCM_TABLES
|
||||
int x, y, z, t;
|
||||
#endif
|
||||
|
||||
LTC_ARGCHK(gcm != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
#ifdef LTC_FAST
|
||||
if (16 % sizeof(LTC_FAST_TYPE)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* is cipher valid? */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (cipher_descriptor[cipher].block_length != 16) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
|
||||
/* schedule key */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* H = E(0) */
|
||||
zeromem(B, 16);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* setup state */
|
||||
zeromem(gcm->buf, sizeof(gcm->buf));
|
||||
zeromem(gcm->X, sizeof(gcm->X));
|
||||
gcm->cipher = cipher;
|
||||
gcm->mode = LTC_GCM_MODE_IV;
|
||||
gcm->ivmode = 0;
|
||||
gcm->buflen = 0;
|
||||
gcm->totlen = 0;
|
||||
gcm->pttotlen = 0;
|
||||
|
||||
#ifdef LTC_GCM_TABLES
|
||||
/* setup tables */
|
||||
|
||||
/* generate the first table as it has no shifting (from which we make the other tables) */
|
||||
zeromem(B, 16);
|
||||
for (y = 0; y < 256; y++) {
|
||||
B[0] = y;
|
||||
gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
|
||||
}
|
||||
|
||||
/* now generate the rest of the tables based the previous table */
|
||||
for (x = 1; x < 16; x++) {
|
||||
for (y = 0; y < 256; y++) {
|
||||
/* now shift it right by 8 bits */
|
||||
t = gcm->PC[x-1][y][15];
|
||||
for (z = 15; z > 0; z--) {
|
||||
gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
|
||||
}
|
||||
gcm->PC[x][y][0] = gcm_shift_table[t<<1];
|
||||
gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
114
deps/libtomcrypt/src/encauth/gcm/gcm_memory.c
vendored
Normal file
114
deps/libtomcrypt/src/encauth/gcm/gcm_memory.c
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_memory.c
|
||||
GCM implementation, process a packet, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Process an entire GCM packet in one call.
|
||||
@param cipher Index of cipher to use
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key
|
||||
@param IV The initialization vector
|
||||
@param IVlen The length of the initialization vector
|
||||
@param adata The additional authentication data (header)
|
||||
@param adatalen The length of the adata
|
||||
@param pt The plaintext
|
||||
@param ptlen The length of the plaintext (ciphertext length is the same)
|
||||
@param ct The ciphertext
|
||||
@param tag [out] The MAC tag
|
||||
@param taglen [in/out] The MAC tag length
|
||||
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_memory( int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *IV, unsigned long IVlen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction)
|
||||
{
|
||||
void *orig;
|
||||
gcm_state *gcm;
|
||||
int err;
|
||||
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
|
||||
return cipher_descriptor[cipher].accel_gcm_memory
|
||||
(key, keylen,
|
||||
IV, IVlen,
|
||||
adata, adatalen,
|
||||
pt, ptlen,
|
||||
ct,
|
||||
tag, taglen,
|
||||
direction);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef LTC_GCM_TABLES_SSE2
|
||||
orig = gcm = XMALLOC(sizeof(*gcm));
|
||||
#else
|
||||
orig = gcm = XMALLOC(sizeof(*gcm) + 16);
|
||||
#endif
|
||||
if (gcm == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations
|
||||
* note that we only modify gcm and keep orig intact. This code is not portable
|
||||
* but again it's only for SSE2 anyways, so who cares?
|
||||
*/
|
||||
#ifdef LTC_GCM_TABLES_SSE2
|
||||
if ((unsigned long)gcm & 15) {
|
||||
gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {
|
||||
goto LTC_ERR;
|
||||
}
|
||||
if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) {
|
||||
goto LTC_ERR;
|
||||
}
|
||||
if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) {
|
||||
goto LTC_ERR;
|
||||
}
|
||||
if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) {
|
||||
goto LTC_ERR;
|
||||
}
|
||||
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:
|
||||
gcm_reset(gcm);
|
||||
XFREE(orig);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
47
deps/libtomcrypt/src/encauth/gcm/gcm_mult_h.c
vendored
Normal file
47
deps/libtomcrypt/src/encauth/gcm/gcm_mult_h.c
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_mult_h.c
|
||||
GCM implementation, do the GF mult, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#if defined(LTC_GCM_MODE)
|
||||
/**
|
||||
GCM multiply by H
|
||||
@param gcm The GCM state which holds the H value
|
||||
@param I The value to multiply H by
|
||||
*/
|
||||
void gcm_mult_h(const gcm_state *gcm, unsigned char *I)
|
||||
{
|
||||
unsigned char T[16];
|
||||
#ifdef LTC_GCM_TABLES
|
||||
int x;
|
||||
#ifdef LTC_GCM_TABLES_SSE2
|
||||
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
|
||||
for (x = 1; x < 16; x++) {
|
||||
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
|
||||
}
|
||||
asm("movdqa %%xmm0,(%0)"::"r"(&T));
|
||||
#else
|
||||
int y;
|
||||
XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
|
||||
for (x = 1; x < 16; x++) {
|
||||
#ifdef LTC_FAST
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(T + y)) ^= *(LTC_FAST_TYPE_PTR_CAST(&gcm->PC[x][I[x]][y]));
|
||||
}
|
||||
#else
|
||||
for (y = 0; y < 16; y++) {
|
||||
T[y] ^= gcm->PC[x][I[x]][y];
|
||||
}
|
||||
#endif /* LTC_FAST */
|
||||
}
|
||||
#endif /* LTC_GCM_TABLES_SSE2 */
|
||||
#else
|
||||
gcm_gf_mult(gcm->H, I, T);
|
||||
#endif
|
||||
XMEMCPY(I, T, 16);
|
||||
}
|
||||
#endif
|
150
deps/libtomcrypt/src/encauth/gcm/gcm_process.c
vendored
Normal file
150
deps/libtomcrypt/src/encauth/gcm/gcm_process.c
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_process.c
|
||||
GCM implementation, process message data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Process plaintext/ciphertext through GCM
|
||||
@param gcm The GCM state
|
||||
@param pt The plaintext
|
||||
@param ptlen The plaintext length (ciphertext length is the same)
|
||||
@param ct The ciphertext
|
||||
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_process(gcm_state *gcm,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
int direction)
|
||||
{
|
||||
unsigned long x;
|
||||
int y, err;
|
||||
unsigned char b;
|
||||
|
||||
LTC_ARGCHK(gcm != NULL);
|
||||
if (ptlen > 0) {
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
}
|
||||
|
||||
if (gcm->buflen > 16 || gcm->buflen < 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 0xFFFFFFFE0 = ((2^39)-256)/8 */
|
||||
if (gcm->pttotlen / 8 + (ulong64)gcm->buflen + (ulong64)ptlen >= CONST64(0xFFFFFFFE0)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (gcm->mode == LTC_GCM_MODE_IV) {
|
||||
/* let's process the IV */
|
||||
if ((err = gcm_add_aad(gcm, NULL, 0)) != CRYPT_OK) return err;
|
||||
}
|
||||
|
||||
/* in AAD mode? */
|
||||
if (gcm->mode == LTC_GCM_MODE_AAD) {
|
||||
/* let's process the AAD */
|
||||
if (gcm->buflen) {
|
||||
gcm->totlen += gcm->buflen * CONST64(8);
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
}
|
||||
|
||||
/* increment counter */
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y] & 255) { break; }
|
||||
}
|
||||
/* encrypt the counter */
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
gcm->buflen = 0;
|
||||
gcm->mode = LTC_GCM_MODE_TEXT;
|
||||
}
|
||||
|
||||
if (gcm->mode != LTC_GCM_MODE_TEXT) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
#ifdef LTC_FAST
|
||||
if (gcm->buflen == 0) {
|
||||
if (direction == GCM_ENCRYPT) {
|
||||
for (x = 0; x < (ptlen & ~15); x += 16) {
|
||||
/* ctr encrypt */
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&ct[x + y])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[x+y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&gcm->buf[y]));
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y]));
|
||||
}
|
||||
/* GMAC it */
|
||||
gcm->pttotlen += 128;
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
/* increment counter */
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y] & 255) { break; }
|
||||
}
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < (ptlen & ~15); x += 16) {
|
||||
/* ctr encrypt */
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y]));
|
||||
*(LTC_FAST_TYPE_PTR_CAST(&pt[x + y])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&gcm->buf[y]));
|
||||
}
|
||||
/* GMAC it */
|
||||
gcm->pttotlen += 128;
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
/* increment counter */
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y] & 255) { break; }
|
||||
}
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* process text */
|
||||
for (; x < ptlen; x++) {
|
||||
if (gcm->buflen == 16) {
|
||||
gcm->pttotlen += 128;
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
|
||||
/* increment counter */
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y] & 255) { break; }
|
||||
}
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
gcm->buflen = 0;
|
||||
}
|
||||
|
||||
if (direction == GCM_ENCRYPT) {
|
||||
b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen];
|
||||
} else {
|
||||
b = ct[x];
|
||||
pt[x] = ct[x] ^ gcm->buf[gcm->buflen];
|
||||
}
|
||||
gcm->X[gcm->buflen++] ^= b;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
32
deps/libtomcrypt/src/encauth/gcm/gcm_reset.c
vendored
Normal file
32
deps/libtomcrypt/src/encauth/gcm/gcm_reset.c
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_reset.c
|
||||
GCM implementation, reset a used state so it can accept IV data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Reset a GCM state to as if you just called gcm_init(). This saves the initialization time.
|
||||
@param gcm The GCM state to reset
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_reset(gcm_state *gcm)
|
||||
{
|
||||
LTC_ARGCHK(gcm != NULL);
|
||||
|
||||
zeromem(gcm->buf, sizeof(gcm->buf));
|
||||
zeromem(gcm->X, sizeof(gcm->X));
|
||||
gcm->mode = LTC_GCM_MODE_IV;
|
||||
gcm->ivmode = 0;
|
||||
gcm->buflen = 0;
|
||||
gcm->totlen = 0;
|
||||
gcm->pttotlen = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
407
deps/libtomcrypt/src/encauth/gcm/gcm_test.c
vendored
Normal file
407
deps/libtomcrypt/src/encauth/gcm/gcm_test.c
vendored
Normal file
@ -0,0 +1,407 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file gcm_test.c
|
||||
GCM implementation, testing, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_GCM_MODE
|
||||
|
||||
/**
|
||||
Test the GCM code
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int gcm_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
unsigned char K[32];
|
||||
int keylen;
|
||||
unsigned char P[128];
|
||||
unsigned long ptlen;
|
||||
unsigned char A[128];
|
||||
unsigned long alen;
|
||||
unsigned char IV[128];
|
||||
unsigned long IVlen;
|
||||
unsigned char C[128];
|
||||
unsigned char T[16];
|
||||
} tests[] = {
|
||||
|
||||
/* test case #1 */
|
||||
{
|
||||
/* key */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
16,
|
||||
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
0,
|
||||
|
||||
/* AAD data */
|
||||
{ 0 },
|
||||
0,
|
||||
|
||||
/* IV */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 },
|
||||
12,
|
||||
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
|
||||
/* tag */
|
||||
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
|
||||
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }
|
||||
},
|
||||
|
||||
/* test case #2 */
|
||||
{
|
||||
/* key */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
16,
|
||||
|
||||
/* PT */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
16,
|
||||
|
||||
/* ADATA */
|
||||
{ 0 },
|
||||
0,
|
||||
|
||||
/* IV */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 },
|
||||
12,
|
||||
|
||||
/* CT */
|
||||
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
|
||||
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
|
||||
|
||||
/* TAG */
|
||||
{ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
|
||||
0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }
|
||||
},
|
||||
|
||||
/* test case #3 */
|
||||
{
|
||||
/* key */
|
||||
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
|
||||
16,
|
||||
|
||||
/* PT */
|
||||
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, },
|
||||
64,
|
||||
|
||||
/* ADATA */
|
||||
{ 0 },
|
||||
0,
|
||||
|
||||
/* IV */
|
||||
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88, },
|
||||
12,
|
||||
|
||||
/* CT */
|
||||
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
|
||||
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
|
||||
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
|
||||
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
|
||||
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
|
||||
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
|
||||
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
|
||||
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, },
|
||||
|
||||
/* TAG */
|
||||
{ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
|
||||
0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, }
|
||||
},
|
||||
|
||||
/* test case #4 */
|
||||
{
|
||||
/* key */
|
||||
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
|
||||
16,
|
||||
|
||||
/* PT */
|
||||
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39, },
|
||||
60,
|
||||
|
||||
/* ADATA */
|
||||
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xab, 0xad, 0xda, 0xd2, },
|
||||
20,
|
||||
|
||||
/* IV */
|
||||
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88, },
|
||||
12,
|
||||
|
||||
/* CT */
|
||||
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
|
||||
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
|
||||
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
|
||||
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
|
||||
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
|
||||
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
|
||||
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
|
||||
0x3d, 0x58, 0xe0, 0x91, },
|
||||
|
||||
/* TAG */
|
||||
{ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
|
||||
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, }
|
||||
|
||||
},
|
||||
|
||||
/* test case #5 */
|
||||
{
|
||||
/* key */
|
||||
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
|
||||
16,
|
||||
|
||||
/* PT */
|
||||
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39, },
|
||||
60,
|
||||
|
||||
/* ADATA */
|
||||
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xab, 0xad, 0xda, 0xd2, },
|
||||
20,
|
||||
|
||||
/* IV */
|
||||
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, },
|
||||
8,
|
||||
|
||||
/* CT */
|
||||
{ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
|
||||
0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
|
||||
0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
|
||||
0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
|
||||
0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
|
||||
0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
|
||||
0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
|
||||
0xc2, 0x3f, 0x45, 0x98, },
|
||||
|
||||
/* TAG */
|
||||
{ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
|
||||
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, }
|
||||
},
|
||||
|
||||
/* test case #6 */
|
||||
{
|
||||
/* key */
|
||||
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
|
||||
16,
|
||||
|
||||
/* PT */
|
||||
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39, },
|
||||
60,
|
||||
|
||||
/* ADATA */
|
||||
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xab, 0xad, 0xda, 0xd2, },
|
||||
20,
|
||||
|
||||
/* IV */
|
||||
{ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
|
||||
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
|
||||
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
|
||||
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
|
||||
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
|
||||
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
|
||||
0xa6, 0x37, 0xb3, 0x9b, },
|
||||
60,
|
||||
|
||||
/* CT */
|
||||
{ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
|
||||
0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
|
||||
0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
|
||||
0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
|
||||
0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
|
||||
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
|
||||
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
|
||||
0x4c, 0x34, 0xae, 0xe5, },
|
||||
|
||||
/* TAG */
|
||||
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
|
||||
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, }
|
||||
},
|
||||
|
||||
/* test case #46 from BG (catches the LTC bug of v1.15) */
|
||||
{
|
||||
/* key */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
16,
|
||||
|
||||
/* PT */
|
||||
{ 0xa2, 0xaa, 0xb3, 0xad, 0x8b, 0x17, 0xac, 0xdd,
|
||||
0xa2, 0x88, 0x42, 0x6c, 0xd7, 0xc4, 0x29, 0xb7,
|
||||
0xca, 0x86, 0xb7, 0xac, 0xa0, 0x58, 0x09, 0xc7,
|
||||
0x0c, 0xe8, 0x2d, 0xb2, 0x57, 0x11, 0xcb, 0x53,
|
||||
0x02, 0xeb, 0x27, 0x43, 0xb0, 0x36, 0xf3, 0xd7,
|
||||
0x50, 0xd6, 0xcf, 0x0d, 0xc0, 0xac, 0xb9, 0x29,
|
||||
0x50, 0xd5, 0x46, 0xdb, 0x30, 0x8f, 0x93, 0xb4,
|
||||
0xff, 0x24, 0x4a, 0xfa, 0x9d, 0xc7, 0x2b, 0xcd,
|
||||
0x75, 0x8d, 0x2c },
|
||||
67,
|
||||
|
||||
/* ADATA */
|
||||
{ 0x68, 0x8e, 0x1a, 0xa9, 0x84, 0xde, 0x92, 0x6d,
|
||||
0xc7, 0xb4, 0xc4, 0x7f, 0x44 },
|
||||
13,
|
||||
|
||||
/* IV */
|
||||
{ 0xb7, 0x21, 0x38, 0xb5, 0xa0, 0x5f, 0xf5, 0x07,
|
||||
0x0e, 0x8c, 0xd9, 0x41, 0x83, 0xf7, 0x61, 0xd8 },
|
||||
16,
|
||||
|
||||
/* CT */
|
||||
{ 0xcb, 0xc8, 0xd2, 0xf1, 0x54, 0x81, 0xa4, 0xcc,
|
||||
0x7d, 0xd1, 0xe1, 0x9a, 0xaa, 0x83, 0xde, 0x56,
|
||||
0x78, 0x48, 0x3e, 0xc3, 0x59, 0xae, 0x7d, 0xec,
|
||||
0x2a, 0xb8, 0xd5, 0x34, 0xe0, 0x90, 0x6f, 0x4b,
|
||||
0x46, 0x63, 0xfa, 0xff, 0x58, 0xa8, 0xb2, 0xd7,
|
||||
0x33, 0xb8, 0x45, 0xee, 0xf7, 0xc9, 0xb3, 0x31,
|
||||
0xe9, 0xe1, 0x0e, 0xb2, 0x61, 0x2c, 0x99, 0x5f,
|
||||
0xeb, 0x1a, 0xc1, 0x5a, 0x62, 0x86, 0xcc, 0xe8,
|
||||
0xb2, 0x97, 0xa8 },
|
||||
|
||||
/* TAG */
|
||||
{ 0x8d, 0x2d, 0x2a, 0x93, 0x72, 0x62, 0x6f, 0x6b,
|
||||
0xee, 0x85, 0x80, 0x27, 0x6a, 0x63, 0x66, 0xbf }
|
||||
}
|
||||
|
||||
/* rest of test cases are the same except AES key size changes... ignored... */
|
||||
};
|
||||
int idx, err;
|
||||
unsigned long x, y;
|
||||
unsigned char out[2][128], T[2][16];
|
||||
gcm_state gcm;
|
||||
|
||||
/* find aes */
|
||||
idx = find_cipher("aes");
|
||||
if (idx == -1) {
|
||||
idx = find_cipher("rijndael");
|
||||
if (idx == -1) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special test case for empty AAD + empty PT */
|
||||
y = sizeof(T[0]);
|
||||
if ((err = gcm_init(&gcm, idx, tests[0].K, tests[0].keylen)) != CRYPT_OK) return err;
|
||||
if ((err = gcm_add_iv(&gcm, tests[0].IV, tests[0].IVlen)) != CRYPT_OK) return err;
|
||||
/* intentionally skip gcm_add_aad + gcm_process */
|
||||
if ((err = gcm_done(&gcm, T[0], &y)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(T[0], y, tests[0].T, 16, "GCM Encrypt Tag-special", 0)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
y = sizeof(T[0]);
|
||||
if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen,
|
||||
tests[x].IV, tests[x].IVlen,
|
||||
tests[x].A, tests[x].alen,
|
||||
(unsigned char*)tests[x].P, tests[x].ptlen,
|
||||
out[0], T[0], &y, GCM_ENCRYPT)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (compare_testvector(out[0], tests[x].ptlen, tests[x].C, tests[x].ptlen, "GCM CT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if (compare_testvector(T[0], y, tests[x].T, 16, "GCM Encrypt Tag", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
y = sizeof(T[1]);
|
||||
XMEMCPY(T[1], tests[x].T, 16);
|
||||
if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen,
|
||||
tests[x].IV, tests[x].IVlen,
|
||||
tests[x].A, tests[x].alen,
|
||||
out[1], tests[x].ptlen,
|
||||
out[0], T[1], &y, GCM_DECRYPT)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (compare_testvector(out[1], tests[x].ptlen, tests[x].P, tests[x].ptlen, "GCM PT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
/* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/451 */
|
||||
{
|
||||
unsigned char key[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
|
||||
unsigned char iv[] = { 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b };
|
||||
unsigned char valid_tag[] = { 0xd8,0x84,0x7d,0xbc,0x32,0x6a,0x06,0xe9,0x88,0xc7,0x7a,0xd3,0x86,0x3e,0x60,0x83 };
|
||||
unsigned char invalid_tag[] = { 0xd9,0x84,0x7d,0xbc,0x32,0x6a,0x06,0xe9,0x88,0xc7,0x7a,0xd3,0x86,0x3e,0x60,0x83 };
|
||||
unsigned char msg[] = { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f };
|
||||
unsigned char ct[] = { 0xeb,0x15,0x6d,0x08,0x1e,0xd6,0xb6,0xb5,0x5f,0x46,0x12,0xf0,0x21,0xd8,0x7b,0x39 };
|
||||
unsigned char pt[20] = { 0 };
|
||||
unsigned long taglen;
|
||||
|
||||
/* VALID tag */
|
||||
taglen = sizeof(valid_tag);
|
||||
err = gcm_memory(idx, key, sizeof(key), iv, sizeof(iv), NULL, 0,
|
||||
pt, sizeof(ct), ct, valid_tag, &taglen, GCM_DECRYPT);
|
||||
if ((err != CRYPT_OK) || (XMEMCMP(msg, pt, sizeof(msg)) != 0)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* INVALID tag */
|
||||
taglen = sizeof(invalid_tag);
|
||||
err = gcm_memory(idx, key, sizeof(key), iv, sizeof(iv), NULL, 0,
|
||||
pt, sizeof(ct), ct, invalid_tag, &taglen, GCM_DECRYPT);
|
||||
if (err == CRYPT_OK) {
|
||||
return CRYPT_FAIL_TESTVECTOR; /* should fail */
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
67
deps/libtomcrypt/src/encauth/ocb/ocb_decrypt.c
vendored
Normal file
67
deps/libtomcrypt/src/encauth/ocb/ocb_decrypt.c
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_decrypt.c
|
||||
OCB implementation, decrypt data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Decrypt a block with OCB.
|
||||
@param ocb The OCB state
|
||||
@param ct The ciphertext (length of the block size of the block cipher)
|
||||
@param pt [out] The plaintext (length of ct)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
|
||||
{
|
||||
unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
|
||||
int err, x;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
|
||||
/* check if valid cipher */
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
LTC_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL);
|
||||
|
||||
/* check length */
|
||||
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Get Z[i] value */
|
||||
ocb_shift_xor(ocb, Z);
|
||||
|
||||
/* xor ct in, encrypt, xor Z out */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
tmp[x] = ct[x] ^ Z[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
pt[x] ^= Z[x];
|
||||
}
|
||||
|
||||
/* compute checksum */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->checksum[x] ^= pt[x];
|
||||
}
|
||||
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(Z, sizeof(Z));
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
74
deps/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c
vendored
Normal file
74
deps/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_decrypt_verify_memory.c
|
||||
OCB implementation, helper to decrypt block of memory, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Decrypt and compare the tag with OCB.
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce (length of the block size of the block cipher)
|
||||
@param ct The ciphertext
|
||||
@param ctlen The length of the ciphertext (octets)
|
||||
@param pt [out] The plaintext
|
||||
@param tag The tag to compare against
|
||||
@param taglen The length of the tag (octets)
|
||||
@param stat [out] The result of the tag comparison (1==valid, 0==invalid)
|
||||
@return CRYPT_OK if successful regardless of the tag comparison
|
||||
*/
|
||||
int ocb_decrypt_verify_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tag, unsigned long taglen,
|
||||
int *stat)
|
||||
{
|
||||
int err;
|
||||
ocb_state *ocb;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
|
||||
/* allocate memory */
|
||||
ocb = XMALLOC(sizeof(ocb_state));
|
||||
if (ocb == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
while (ctlen > (unsigned long)ocb->block_len) {
|
||||
if ((err = ocb_decrypt(ocb, ct, pt)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ctlen -= ocb->block_len;
|
||||
pt += ocb->block_len;
|
||||
ct += ocb->block_len;
|
||||
}
|
||||
|
||||
err = ocb_done_decrypt(ocb, ct, ctlen, pt, tag, taglen, stat);
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(ocb, sizeof(ocb_state));
|
||||
#endif
|
||||
|
||||
XFREE(ocb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
68
deps/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c
vendored
Normal file
68
deps/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_done_decrypt.c
|
||||
OCB implementation, terminate decryption, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Terminate a decrypting OCB state
|
||||
@param ocb The OCB state
|
||||
@param ct The ciphertext (if any)
|
||||
@param ctlen The length of the ciphertext (octets)
|
||||
@param pt [out] The plaintext
|
||||
@param tag The authentication tag (to compare against)
|
||||
@param taglen The length of the authentication tag provided
|
||||
@param stat [out] The result of the tag comparison
|
||||
@return CRYPT_OK if the process was successful regardless if the tag is valid
|
||||
*/
|
||||
int ocb_done_decrypt(ocb_state *ocb,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tag, unsigned long taglen, int *stat)
|
||||
{
|
||||
int err;
|
||||
unsigned char *tagbuf;
|
||||
unsigned long tagbuflen;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
|
||||
/* default to failed */
|
||||
*stat = 0;
|
||||
|
||||
/* allocate memory */
|
||||
tagbuf = XMALLOC(MAXBLOCKSIZE);
|
||||
if (tagbuf == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
tagbuflen = MAXBLOCKSIZE;
|
||||
if ((err = s_ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if (taglen <= tagbuflen && XMEM_NEQ(tagbuf, tag, taglen) == 0) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(tagbuf, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(tagbuf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
34
deps/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c
vendored
Normal file
34
deps/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_done_encrypt.c
|
||||
OCB implementation, terminate encryption, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Terminate an encryption OCB state
|
||||
@param ocb The OCB state
|
||||
@param pt Remaining plaintext (if any)
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [out] The ciphertext (if any)
|
||||
@param tag [out] The tag for the OCB stream
|
||||
@param taglen [in/out] The max size and resulting size of the tag
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct, unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
return s_ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
60
deps/libtomcrypt/src/encauth/ocb/ocb_encrypt.c
vendored
Normal file
60
deps/libtomcrypt/src/encauth/ocb/ocb_encrypt.c
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_encrypt.c
|
||||
OCB implementation, encrypt data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Encrypt a block of data with OCB.
|
||||
@param ocb The OCB state
|
||||
@param pt The plaintext (length of the block size of the block cipher)
|
||||
@param ct [out] The ciphertext (same size as the pt)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
|
||||
{
|
||||
unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
|
||||
int err, x;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* compute checksum */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->checksum[x] ^= pt[x];
|
||||
}
|
||||
|
||||
/* Get Z[i] value */
|
||||
ocb_shift_xor(ocb, Z);
|
||||
|
||||
/* xor pt in, encrypt, xor Z out */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
tmp[x] = pt[x] ^ Z[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ct[x] ^= Z[x];
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(Z, sizeof(Z));
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
72
deps/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c
vendored
Normal file
72
deps/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_encrypt_authenticate_memory.c
|
||||
OCB implementation, encrypt block of memory, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Encrypt and generate an authentication code for a buffer of memory
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce (length of the block ciphers block size)
|
||||
@param pt The plaintext
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [out] The ciphertext
|
||||
@param tag [out] The authentication tag
|
||||
@param taglen [in/out] The max size and resulting size of the authentication tag
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb_encrypt_authenticate_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
int err;
|
||||
ocb_state *ocb;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
/* allocate ram */
|
||||
ocb = XMALLOC(sizeof(ocb_state));
|
||||
if (ocb == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
while (ptlen > (unsigned long)ocb->block_len) {
|
||||
if ((err = ocb_encrypt(ocb, pt, ct)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ptlen -= ocb->block_len;
|
||||
pt += ocb->block_len;
|
||||
ct += ocb->block_len;
|
||||
}
|
||||
|
||||
err = ocb_done_encrypt(ocb, pt, ptlen, ct, tag, taglen);
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(ocb, sizeof(ocb_state));
|
||||
#endif
|
||||
|
||||
XFREE(ocb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
129
deps/libtomcrypt/src/encauth/ocb/ocb_init.c
vendored
Normal file
129
deps/libtomcrypt/src/encauth/ocb/ocb_init.c
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_init.c
|
||||
OCB implementation, initialize state, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
static const struct {
|
||||
int len;
|
||||
unsigned char poly_div[MAXBLOCKSIZE],
|
||||
poly_mul[MAXBLOCKSIZE];
|
||||
} polys[] = {
|
||||
{
|
||||
8,
|
||||
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
|
||||
}, {
|
||||
16,
|
||||
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize an OCB context.
|
||||
@param ocb [out] The destination of the OCB state
|
||||
@param cipher The index of the desired cipher
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce (length of the block size of the cipher)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb_init(ocb_state *ocb, int cipher,
|
||||
const unsigned char *key, unsigned long keylen, const unsigned char *nonce)
|
||||
{
|
||||
int poly, x, y, m, err;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
|
||||
/* valid cipher? */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* determine which polys to use */
|
||||
ocb->block_len = cipher_descriptor[cipher].block_length;
|
||||
x = (int)(sizeof(polys)/sizeof(polys[0]));
|
||||
for (poly = 0; poly < x; poly++) {
|
||||
if (polys[poly].len == ocb->block_len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (poly == x) {
|
||||
return CRYPT_INVALID_ARG; /* block_len not found in polys */
|
||||
}
|
||||
if (polys[poly].len != ocb->block_len) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* schedule the key */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find L = E[0] */
|
||||
zeromem(ocb->L, ocb->block_len);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find R = E[N xor L] */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->R[x] = ocb->L[x] ^ nonce[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find Ls[i] = L << i for i == 0..31 */
|
||||
XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);
|
||||
for (x = 1; x < 32; x++) {
|
||||
m = ocb->Ls[x-1][0] >> 7;
|
||||
for (y = 0; y < ocb->block_len-1; y++) {
|
||||
ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255;
|
||||
}
|
||||
ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255;
|
||||
|
||||
if (m == 1) {
|
||||
for (y = 0; y < ocb->block_len; y++) {
|
||||
ocb->Ls[x][y] ^= polys[poly].poly_mul[y];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* find Lr = L / x */
|
||||
m = ocb->L[ocb->block_len-1] & 1;
|
||||
|
||||
/* shift right */
|
||||
for (x = ocb->block_len - 1; x > 0; x--) {
|
||||
ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255;
|
||||
}
|
||||
ocb->Lr[0] = ocb->L[0] >> 1;
|
||||
|
||||
if (m == 1) {
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->Lr[x] ^= polys[poly].poly_div[x];
|
||||
}
|
||||
}
|
||||
|
||||
/* set Li, checksum */
|
||||
zeromem(ocb->Li, ocb->block_len);
|
||||
zeromem(ocb->checksum, ocb->block_len);
|
||||
|
||||
/* set other params */
|
||||
ocb->block_index = 1;
|
||||
ocb->cipher = cipher;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
30
deps/libtomcrypt/src/encauth/ocb/ocb_ntz.c
vendored
Normal file
30
deps/libtomcrypt/src/encauth/ocb/ocb_ntz.c
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_ntz.c
|
||||
OCB implementation, internal function, by Tom St Denis
|
||||
*/
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Returns the number of leading zero bits [from lsb up]
|
||||
@param x The 32-bit value to observe
|
||||
@return The number of bits [from the lsb up] that are zero
|
||||
*/
|
||||
int ocb_ntz(unsigned long x)
|
||||
{
|
||||
int c;
|
||||
x &= 0xFFFFFFFFUL;
|
||||
c = 0;
|
||||
while ((x & 1) == 0) {
|
||||
++c;
|
||||
x >>= 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
27
deps/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c
vendored
Normal file
27
deps/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_shift_xor.c
|
||||
OCB implementation, internal function, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Compute the shift/xor for OCB (internal function)
|
||||
@param ocb The OCB state
|
||||
@param Z The destination of the shift
|
||||
*/
|
||||
void ocb_shift_xor(ocb_state *ocb, unsigned char *Z)
|
||||
{
|
||||
int x, y;
|
||||
y = ocb_ntz(ocb->block_index++);
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->Li[x] ^= ocb->Ls[y][x];
|
||||
Z[x] = ocb->Li[x] ^ ocb->R[x];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
205
deps/libtomcrypt/src/encauth/ocb/ocb_test.c
vendored
Normal file
205
deps/libtomcrypt/src/encauth/ocb/ocb_test.c
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb_test.c
|
||||
OCB implementation, self-test by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/**
|
||||
Test the OCB protocol
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
int ptlen;
|
||||
unsigned char key[16], nonce[16], pt[34], ct[34], tag[16];
|
||||
} tests[] = {
|
||||
|
||||
/* OCB-AES-128-0B */
|
||||
{
|
||||
0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
/* pt */
|
||||
{ 0 },
|
||||
/* ct */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6,
|
||||
0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee },
|
||||
},
|
||||
|
||||
|
||||
/* OCB-AES-128-3B */
|
||||
{
|
||||
3,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
/* pt */
|
||||
{ 0x00, 0x01, 0x02 },
|
||||
/* ct */
|
||||
{ 0xfc, 0xd3, 0x7d },
|
||||
/* tag */
|
||||
{ 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a,
|
||||
0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba },
|
||||
},
|
||||
|
||||
/* OCB-AES-128-16B */
|
||||
{
|
||||
16,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
/* pt */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* ct */
|
||||
{ 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3,
|
||||
0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 },
|
||||
/* tag */
|
||||
{ 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71,
|
||||
0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf },
|
||||
},
|
||||
|
||||
/* OCB-AES-128-20B */
|
||||
{
|
||||
20,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
/* pt */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13 },
|
||||
/* ct */
|
||||
{ 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
|
||||
0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
|
||||
0x70, 0x03, 0xeb, 0x55},
|
||||
/* tag */
|
||||
{ 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77,
|
||||
0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb },
|
||||
},
|
||||
|
||||
/* OCB-AES-128-32B */
|
||||
{
|
||||
32,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
/* pt */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
|
||||
/* ct */
|
||||
{ 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
|
||||
0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
|
||||
0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8,
|
||||
0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa },
|
||||
|
||||
/* tag */
|
||||
{ 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c,
|
||||
0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf },
|
||||
},
|
||||
|
||||
/* OCB-AES-128-34B */
|
||||
{
|
||||
34,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
/* pt */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21 },
|
||||
/* ct */
|
||||
{ 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
|
||||
0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
|
||||
0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa,
|
||||
0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f,
|
||||
0xa9, 0x5d },
|
||||
|
||||
/* tag */
|
||||
{ 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf,
|
||||
0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab },
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
int err, x, idx, res;
|
||||
unsigned long len;
|
||||
unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE];
|
||||
|
||||
/* AES can be under rijndael or aes... try to find it */
|
||||
if ((idx = find_cipher("aes")) == -1) {
|
||||
if ((idx = find_cipher("rijndael")) == -1) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
len = sizeof(outtag);
|
||||
if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16,
|
||||
tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (compare_testvector(outtag, len, tests[x].tag, sizeof(tests[x].tag), "OCB Tag", x) ||
|
||||
compare_testvector(outct, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "OCB CT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen,
|
||||
outct, tests[x].tag, len, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || compare_testvector(outct, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "OCB", x)) {
|
||||
#ifdef LTC_TEST_DBG
|
||||
printf("\n\nOCB: Failure-decrypt - res = %d\n", res);
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif /* LTC_TEST */
|
||||
}
|
||||
|
||||
#endif /* LTC_OCB_MODE */
|
||||
|
||||
|
||||
/* some comments
|
||||
|
||||
-- it's hard to seek
|
||||
-- hard to stream [you can't emit ciphertext until full block]
|
||||
-- The setup is somewhat complicated...
|
||||
*/
|
136
deps/libtomcrypt/src/encauth/ocb/s_ocb_done.c
vendored
Normal file
136
deps/libtomcrypt/src/encauth/ocb/s_ocb_done.c
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file s_ocb_done.c
|
||||
OCB implementation, internal helper, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB_MODE
|
||||
|
||||
/* Since the last block is encrypted in CTR mode the same code can
|
||||
* be used to finish a decrypt or encrypt stream. The only difference
|
||||
* is we XOR the final ciphertext into the checksum so we have to xor it
|
||||
* before we CTR [decrypt] or after [encrypt]
|
||||
*
|
||||
* the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it...
|
||||
*/
|
||||
|
||||
/**
|
||||
Shared code to finish an OCB stream
|
||||
@param ocb The OCB state
|
||||
@param pt The remaining plaintext [or input]
|
||||
@param ptlen The length of the input (octets)
|
||||
@param ct [out] The output buffer
|
||||
@param tag [out] The destination for the authentication tag
|
||||
@param taglen [in/out] The max size and resulting size of the authentication tag
|
||||
@param mode The mode we are terminating, 0==encrypt, 1==decrypt
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode)
|
||||
|
||||
{
|
||||
unsigned char *Z, *Y, *X;
|
||||
int err, x;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length ||
|
||||
(int)ptlen > ocb->block_len || (int)ptlen < 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* allocate ram */
|
||||
Z = XMALLOC(MAXBLOCKSIZE);
|
||||
Y = XMALLOC(MAXBLOCKSIZE);
|
||||
X = XMALLOC(MAXBLOCKSIZE);
|
||||
if (X == NULL || Y == NULL || Z == NULL) {
|
||||
if (X != NULL) {
|
||||
XFREE(X);
|
||||
}
|
||||
if (Y != NULL) {
|
||||
XFREE(Y);
|
||||
}
|
||||
if (Z != NULL) {
|
||||
XFREE(Z);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */
|
||||
ocb_shift_xor(ocb, X);
|
||||
XMEMCPY(Z, X, ocb->block_len);
|
||||
|
||||
X[ocb->block_len-1] ^= (ptlen*8)&255;
|
||||
X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255;
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
X[x] ^= ocb->Lr[x];
|
||||
}
|
||||
|
||||
/* Y[m] = E(X[m])) */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mode == 1) {
|
||||
/* decrypt mode, so let's xor it first */
|
||||
/* xor C[m] into checksum */
|
||||
for (x = 0; x < (int)ptlen; x++) {
|
||||
ocb->checksum[x] ^= ct[x];
|
||||
}
|
||||
}
|
||||
|
||||
/* C[m] = P[m] xor Y[m] */
|
||||
for (x = 0; x < (int)ptlen; x++) {
|
||||
ct[x] = pt[x] ^ Y[x];
|
||||
}
|
||||
|
||||
if (mode == 0) {
|
||||
/* encrypt mode */
|
||||
/* xor C[m] into checksum */
|
||||
for (x = 0; x < (int)ptlen; x++) {
|
||||
ocb->checksum[x] ^= ct[x];
|
||||
}
|
||||
}
|
||||
|
||||
/* xor Y[m] and Z[m] into checksum */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->checksum[x] ^= Y[x] ^ Z[x];
|
||||
}
|
||||
|
||||
/* encrypt checksum, er... tag!! */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
cipher_descriptor[ocb->cipher].done(&ocb->key);
|
||||
|
||||
/* now store it */
|
||||
for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) {
|
||||
tag[x] = X[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(X, MAXBLOCKSIZE);
|
||||
zeromem(Y, MAXBLOCKSIZE);
|
||||
zeromem(Z, MAXBLOCKSIZE);
|
||||
zeromem(ocb, sizeof(*ocb));
|
||||
#endif
|
||||
error:
|
||||
XFREE(X);
|
||||
XFREE(Y);
|
||||
XFREE(Z);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
96
deps/libtomcrypt/src/encauth/ocb3/ocb3_add_aad.c
vendored
Normal file
96
deps/libtomcrypt/src/encauth/ocb3/ocb3_add_aad.c
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_add_aad.c
|
||||
OCB implementation, add AAD data, by Karel Miko
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Add one block of AAD data (internal function)
|
||||
@param ocb The OCB state
|
||||
@param aad_block [in] AAD data (block_len size)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
static int s_ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block)
|
||||
{
|
||||
unsigned char tmp[MAXBLOCKSIZE];
|
||||
int err;
|
||||
|
||||
/* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
|
||||
ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len);
|
||||
|
||||
/* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
|
||||
ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len);
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
|
||||
|
||||
ocb->ablock_index++;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Add AAD - additional associated data
|
||||
@param ocb The OCB state
|
||||
@param aad The AAD data
|
||||
@param aadlen The size of AAD data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen)
|
||||
{
|
||||
int err, x, full_blocks, full_blocks_len, last_block_len;
|
||||
unsigned char *data;
|
||||
unsigned long datalen, l;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (aadlen == 0) return CRYPT_OK;
|
||||
LTC_ARGCHK(aad != NULL);
|
||||
|
||||
if (ocb->adata_buffer_bytes > 0) {
|
||||
l = ocb->block_len - ocb->adata_buffer_bytes;
|
||||
if (l > aadlen) l = aadlen;
|
||||
XMEMCPY(ocb->adata_buffer+ocb->adata_buffer_bytes, aad, l);
|
||||
ocb->adata_buffer_bytes += l;
|
||||
|
||||
if (ocb->adata_buffer_bytes == ocb->block_len) {
|
||||
if ((err = s_ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ocb->adata_buffer_bytes = 0;
|
||||
}
|
||||
|
||||
data = (unsigned char *)aad + l;
|
||||
datalen = aadlen - l;
|
||||
}
|
||||
else {
|
||||
data = (unsigned char *)aad;
|
||||
datalen = aadlen;
|
||||
}
|
||||
|
||||
if (datalen == 0) return CRYPT_OK;
|
||||
|
||||
full_blocks = datalen/ocb->block_len;
|
||||
full_blocks_len = full_blocks * ocb->block_len;
|
||||
last_block_len = datalen - full_blocks_len;
|
||||
|
||||
for (x=0; x<full_blocks; x++) {
|
||||
if ((err = s_ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_block_len>0) {
|
||||
XMEMCPY(ocb->adata_buffer, data+full_blocks_len, last_block_len);
|
||||
ocb->adata_buffer_bytes = last_block_len;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
76
deps/libtomcrypt/src/encauth/ocb3/ocb3_decrypt.c
vendored
Normal file
76
deps/libtomcrypt/src/encauth/ocb3/ocb3_decrypt.c
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_decrypt.c
|
||||
OCB implementation, decrypt data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Decrypt blocks of ciphertext with OCB
|
||||
@param ocb The OCB state
|
||||
@param ct The ciphertext (length multiple of the block size of the block cipher)
|
||||
@param ctlen The length of the input (octets)
|
||||
@param pt [out] The plaintext (length of ct)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
|
||||
{
|
||||
unsigned char tmp[MAXBLOCKSIZE];
|
||||
int err, i, full_blocks;
|
||||
unsigned char *pt_b, *ct_b;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (ctlen == 0) return CRYPT_OK; /* no data, nothing to do */
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ctlen % ocb->block_len) { /* ctlen has to bu multiple of block_len */
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
full_blocks = ctlen/ocb->block_len;
|
||||
for(i=0; i<full_blocks; i++) {
|
||||
pt_b = (unsigned char *)pt+i*ocb->block_len;
|
||||
ct_b = (unsigned char *)ct+i*ocb->block_len;
|
||||
|
||||
/* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
|
||||
ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
|
||||
|
||||
/* tmp[] = ct[] XOR ocb->Offset_current[] */
|
||||
ocb3_int_xor_blocks(tmp, ct_b, ocb->Offset_current, ocb->block_len);
|
||||
|
||||
/* decrypt */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* pt[] = tmp[] XOR ocb->Offset_current[] */
|
||||
ocb3_int_xor_blocks(pt_b, tmp, ocb->Offset_current, ocb->block_len);
|
||||
|
||||
/* ocb->checksum[] = ocb->checksum[] XOR pt[] */
|
||||
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
|
||||
|
||||
ocb->block_index++;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
101
deps/libtomcrypt/src/encauth/ocb3/ocb3_decrypt_last.c
vendored
Normal file
101
deps/libtomcrypt/src/encauth/ocb3/ocb3_decrypt_last.c
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_decrypt_last.c
|
||||
OCB implementation, internal helper, by Karel Miko
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Finish an OCB (decryption) stream
|
||||
@param ocb The OCB state
|
||||
@param ct The remaining ciphertext
|
||||
@param ctlen The length of the ciphertext (octets)
|
||||
@param pt [out] The output buffer
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
|
||||
{
|
||||
unsigned char iOffset_star[MAXBLOCKSIZE];
|
||||
unsigned char iPad[MAXBLOCKSIZE];
|
||||
int err, x, full_blocks, full_blocks_len, last_block_len;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (ct == NULL) LTC_ARGCHK(ctlen == 0);
|
||||
if (ctlen != 0) {
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
full_blocks = ctlen/ocb->block_len;
|
||||
full_blocks_len = full_blocks * ocb->block_len;
|
||||
last_block_len = ctlen - full_blocks_len;
|
||||
|
||||
/* process full blocks first */
|
||||
if (full_blocks>0) {
|
||||
if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_block_len>0) {
|
||||
/* Offset_* = Offset_m xor L_* */
|
||||
ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
|
||||
|
||||
/* Pad = ENCIPHER(K, Offset_*) */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* P_* = C_* xor Pad[1..bitlen(C_*)] */
|
||||
ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len);
|
||||
|
||||
/* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
|
||||
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
|
||||
for(x=last_block_len; x<ocb->block_len; x++) {
|
||||
if (x == last_block_len) {
|
||||
ocb->checksum[x] ^= 0x80;
|
||||
} else {
|
||||
ocb->checksum[x] ^= 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
|
||||
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
|
||||
for(x=0; x<ocb->block_len; x++) {
|
||||
ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
|
||||
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
|
||||
for(x=0; x<ocb->block_len; x++) {
|
||||
ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(iOffset_star, MAXBLOCKSIZE);
|
||||
zeromem(iPad, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
100
deps/libtomcrypt/src/encauth/ocb3/ocb3_decrypt_verify_memory.c
vendored
Normal file
100
deps/libtomcrypt/src/encauth/ocb3/ocb3_decrypt_verify_memory.c
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_decrypt_verify_memory.c
|
||||
OCB implementation, helper to decrypt block of memory, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Decrypt and compare the tag with OCB
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce (length of the block size of the block cipher)
|
||||
@param noncelen The length of the nonce (octets)
|
||||
@param adata The AAD - additional associated data
|
||||
@param adatalen The length of AAD (octets)
|
||||
@param ct The ciphertext
|
||||
@param ctlen The length of the ciphertext (octets)
|
||||
@param pt [out] The plaintext
|
||||
@param tag The tag to compare against
|
||||
@param taglen The length of the tag (octets)
|
||||
@param stat [out] The result of the tag comparison (1==valid, 0==invalid)
|
||||
@return CRYPT_OK if successful regardless of the tag comparison
|
||||
*/
|
||||
int ocb3_decrypt_verify_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
const unsigned char *tag, unsigned long taglen,
|
||||
int *stat)
|
||||
{
|
||||
int err;
|
||||
ocb3_state *ocb;
|
||||
unsigned char *buf;
|
||||
unsigned long buflen;
|
||||
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
|
||||
/* default to zero */
|
||||
*stat = 0;
|
||||
|
||||
/* limit taglen */
|
||||
taglen = MIN(taglen, MAXBLOCKSIZE);
|
||||
|
||||
/* allocate memory */
|
||||
buf = XMALLOC(taglen);
|
||||
ocb = XMALLOC(sizeof(ocb3_state));
|
||||
if (ocb == NULL || buf == NULL) {
|
||||
if (ocb != NULL) {
|
||||
XFREE(ocb);
|
||||
}
|
||||
if (buf != NULL) {
|
||||
XFREE(buf);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, taglen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if (adata != NULL || adatalen != 0) {
|
||||
if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = ocb3_decrypt_last(ocb, ct, ctlen, pt)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
buflen = taglen;
|
||||
if ((err = ocb3_done(ocb, buf, &buflen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* compare tags */
|
||||
if (buflen >= taglen && XMEM_NEQ(buf, tag, taglen) == 0) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(ocb, sizeof(ocb3_state));
|
||||
#endif
|
||||
|
||||
XFREE(ocb);
|
||||
XFREE(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
82
deps/libtomcrypt/src/encauth/ocb3/ocb3_done.c
vendored
Normal file
82
deps/libtomcrypt/src/encauth/ocb3/ocb3_done.c
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_done.c
|
||||
OCB implementation, INTERNAL ONLY helper, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Finish OCB processing and compute the tag
|
||||
@param ocb The OCB state
|
||||
@param tag [out] The destination for the authentication tag
|
||||
@param taglen [in/out] The max size and resulting size of the authentication tag
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
unsigned char tmp[MAXBLOCKSIZE];
|
||||
int err, x;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(tag != NULL);
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* check taglen */
|
||||
if ((int)*taglen < ocb->tag_len) {
|
||||
*taglen = (unsigned long)ocb->tag_len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* finalize AAD processing */
|
||||
|
||||
if (ocb->adata_buffer_bytes>0) {
|
||||
/* Offset_* = Offset_m xor L_* */
|
||||
ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);
|
||||
|
||||
/* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
|
||||
ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
|
||||
for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
|
||||
if (x == ocb->adata_buffer_bytes) {
|
||||
tmp[x] = 0x80 ^ ocb->aOffset_current[x];
|
||||
}
|
||||
else {
|
||||
tmp[x] = 0x00 ^ ocb->aOffset_current[x];
|
||||
}
|
||||
}
|
||||
|
||||
/* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
|
||||
}
|
||||
|
||||
/* finalize TAG computing */
|
||||
|
||||
/* at this point ocb->aSum_current = HASH(K, A) */
|
||||
/* tag = tag ^ HASH(K, A) */
|
||||
ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);
|
||||
|
||||
/* copy tag bytes */
|
||||
for(x = 0; x < ocb->tag_len; x++) tag[x] = tmp[x];
|
||||
*taglen = (unsigned long)ocb->tag_len;
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(tmp, MAXBLOCKSIZE);
|
||||
zeromem(ocb, sizeof(*ocb));
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
76
deps/libtomcrypt/src/encauth/ocb3/ocb3_encrypt.c
vendored
Normal file
76
deps/libtomcrypt/src/encauth/ocb3/ocb3_encrypt.c
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_encrypt.c
|
||||
OCB implementation, encrypt data, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Encrypt blocks of data with OCB
|
||||
@param ocb The OCB state
|
||||
@param pt The plaintext (length multiple of the block size of the block cipher)
|
||||
@param ptlen The length of the input (octets)
|
||||
@param ct [out] The ciphertext (same size as the pt)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
|
||||
{
|
||||
unsigned char tmp[MAXBLOCKSIZE];
|
||||
int err, i, full_blocks;
|
||||
unsigned char *pt_b, *ct_b;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (ptlen == 0) return CRYPT_OK; /* no data, nothing to do */
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
full_blocks = ptlen/ocb->block_len;
|
||||
for(i=0; i<full_blocks; i++) {
|
||||
pt_b = (unsigned char *)pt+i*ocb->block_len;
|
||||
ct_b = (unsigned char *)ct+i*ocb->block_len;
|
||||
|
||||
/* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
|
||||
ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
|
||||
|
||||
/* tmp[] = pt[] XOR ocb->Offset_current[] */
|
||||
ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len);
|
||||
|
||||
/* encrypt */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* ct[] = tmp[] XOR ocb->Offset_current[] */
|
||||
ocb3_int_xor_blocks(ct_b, tmp, ocb->Offset_current, ocb->block_len);
|
||||
|
||||
/* ocb->checksum[] = ocb->checksum[] XOR pt[] */
|
||||
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
|
||||
|
||||
ocb->block_index++;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
72
deps/libtomcrypt/src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
vendored
Normal file
72
deps/libtomcrypt/src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_encrypt_authenticate_memory.c
|
||||
OCB implementation, encrypt block of memory, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Encrypt and generate an authentication code for a buffer of memory
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce (length of the block ciphers block size)
|
||||
@param noncelen The length of the nonce (octets)
|
||||
@param adata The AAD - additional associated data
|
||||
@param adatalen The length of AAD (octets)
|
||||
@param pt The plaintext
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [out] The ciphertext
|
||||
@param tag [out] The authentication tag
|
||||
@param taglen [in/out] The max size and resulting size of the authentication tag
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_encrypt_authenticate_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
int err;
|
||||
ocb3_state *ocb;
|
||||
|
||||
LTC_ARGCHK(taglen != NULL);
|
||||
|
||||
/* allocate memory */
|
||||
ocb = XMALLOC(sizeof(ocb3_state));
|
||||
if (ocb == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, *taglen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if (adata != NULL || adatalen != 0) {
|
||||
if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = ocb3_encrypt_last(ocb, pt, ptlen, ct)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
err = ocb3_done(ocb, tag, taglen);
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(ocb, sizeof(ocb3_state));
|
||||
#endif
|
||||
|
||||
XFREE(ocb);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
102
deps/libtomcrypt/src/encauth/ocb3/ocb3_encrypt_last.c
vendored
Normal file
102
deps/libtomcrypt/src/encauth/ocb3/ocb3_encrypt_last.c
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_encrypt_last.c
|
||||
OCB implementation, internal helper, by Karel Miko
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Finish an OCB (encryption) stream
|
||||
@param ocb The OCB state
|
||||
@param pt The remaining plaintext
|
||||
@param ptlen The length of the plaintext (octets)
|
||||
@param ct [out] The output buffer
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
|
||||
{
|
||||
unsigned char iOffset_star[MAXBLOCKSIZE];
|
||||
unsigned char iPad[MAXBLOCKSIZE];
|
||||
int err, x, full_blocks, full_blocks_len, last_block_len;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (pt == NULL) LTC_ARGCHK(ptlen == 0);
|
||||
if (ptlen != 0) {
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
full_blocks = ptlen/ocb->block_len;
|
||||
full_blocks_len = full_blocks * ocb->block_len;
|
||||
last_block_len = ptlen - full_blocks_len;
|
||||
|
||||
/* process full blocks first */
|
||||
if (full_blocks>0) {
|
||||
if ((err = ocb3_encrypt(ocb, pt, full_blocks_len, ct)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/* at this point: m = ocb->block_index (last block index), Offset_m = ocb->Offset_current */
|
||||
|
||||
if (last_block_len>0) {
|
||||
/* Offset_* = Offset_m xor L_* */
|
||||
ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
|
||||
|
||||
/* Pad = ENCIPHER(K, Offset_*) */
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* C_* = P_* xor Pad[1..bitlen(P_*)] */
|
||||
ocb3_int_xor_blocks(ct+full_blocks_len, pt+full_blocks_len, iPad, last_block_len);
|
||||
|
||||
/* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
|
||||
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
|
||||
for(x=last_block_len; x<ocb->block_len; x++) {
|
||||
if (x == last_block_len) {
|
||||
ocb->checksum[x] ^= 0x80;
|
||||
} else {
|
||||
ocb->checksum[x] ^= 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
|
||||
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
|
||||
for(x=0; x<ocb->block_len; x++) {
|
||||
ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
} else {
|
||||
/* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
|
||||
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
|
||||
for(x=0; x<ocb->block_len; x++) {
|
||||
ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
|
||||
}
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(iOffset_star, MAXBLOCKSIZE);
|
||||
zeromem(iPad, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
186
deps/libtomcrypt/src/encauth/ocb3/ocb3_init.c
vendored
Normal file
186
deps/libtomcrypt/src/encauth/ocb3/ocb3_init.c
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_init.c
|
||||
OCB implementation, initialize state, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
static void s_ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen)
|
||||
{
|
||||
int x, y, bottom;
|
||||
int idx, shift;
|
||||
unsigned char iNonce[MAXBLOCKSIZE];
|
||||
unsigned char iKtop[MAXBLOCKSIZE];
|
||||
unsigned char iStretch[MAXBLOCKSIZE+8];
|
||||
|
||||
/* Nonce = zeros(127-bitlen(N)) || 1 || N */
|
||||
zeromem(iNonce, sizeof(iNonce));
|
||||
for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) {
|
||||
iNonce[x] = nonce[noncelen-y-1];
|
||||
}
|
||||
iNonce[x] = 0x01;
|
||||
iNonce[0] |= ((taglen*8) % 128) << 1;
|
||||
|
||||
/* bottom = str2num(Nonce[123..128]) */
|
||||
bottom = iNonce[ocb->block_len-1] & 0x3F;
|
||||
|
||||
/* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
|
||||
iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0;
|
||||
if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) {
|
||||
zeromem(ocb->Offset_current, ocb->block_len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
iStretch[x] = iKtop[x];
|
||||
}
|
||||
for (y = 0; y < 8; y++) {
|
||||
iStretch[x+y] = iKtop[y] ^ iKtop[y+1];
|
||||
}
|
||||
|
||||
/* Offset_0 = Stretch[1+bottom..128+bottom] */
|
||||
idx = bottom / 8;
|
||||
shift = (bottom % 8);
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->Offset_current[x] = iStretch[idx+x] << shift;
|
||||
if (shift > 0) {
|
||||
ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
int len;
|
||||
unsigned char poly_mul[MAXBLOCKSIZE];
|
||||
} polys[] = {
|
||||
{
|
||||
8,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
|
||||
}, {
|
||||
16,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize an OCB context
|
||||
@param ocb [out] The destination of the OCB state
|
||||
@param cipher The index of the desired cipher
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param nonce The session nonce
|
||||
@param noncelen The length of the session nonce (octets, up to 15)
|
||||
@param taglen The length of the tag (octets, up to 16)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_init(ocb3_state *ocb, int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
unsigned long taglen)
|
||||
{
|
||||
int poly, x, y, m, err;
|
||||
unsigned char *previous, *current;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
|
||||
/* valid cipher? */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ocb->cipher = cipher;
|
||||
|
||||
/* Valid Nonce?
|
||||
* As of RFC7253: "string of no more than 120 bits" */
|
||||
if (noncelen > (120/8)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* The blockcipher must have a 128-bit blocksize */
|
||||
if (cipher_descriptor[cipher].block_length != 16) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* The TAGLEN may be any value up to 128 (bits) */
|
||||
if (taglen > 16) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
ocb->tag_len = taglen;
|
||||
|
||||
/* determine which polys to use */
|
||||
ocb->block_len = cipher_descriptor[cipher].block_length;
|
||||
x = (int)(sizeof(polys)/sizeof(polys[0]));
|
||||
for (poly = 0; poly < x; poly++) {
|
||||
if (polys[poly].len == ocb->block_len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (poly == x) {
|
||||
return CRYPT_INVALID_ARG; /* block_len not found in polys */
|
||||
}
|
||||
if (polys[poly].len != ocb->block_len) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* schedule the key */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* L_* = ENCIPHER(K, zeros(128)) */
|
||||
zeromem(ocb->L_star, ocb->block_len);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* compute L_$, L_0, L_1, ... */
|
||||
for (x = -1; x < 32; x++) {
|
||||
if (x == -1) { /* gonna compute: L_$ = double(L_*) */
|
||||
current = ocb->L_dollar;
|
||||
previous = ocb->L_star;
|
||||
}
|
||||
else if (x == 0) { /* gonna compute: L_0 = double(L_$) */
|
||||
current = ocb->L_[0];
|
||||
previous = ocb->L_dollar;
|
||||
}
|
||||
else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */
|
||||
current = ocb->L_[x];
|
||||
previous = ocb->L_[x-1];
|
||||
}
|
||||
m = previous[0] >> 7;
|
||||
for (y = 0; y < ocb->block_len-1; y++) {
|
||||
current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255;
|
||||
}
|
||||
current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255;
|
||||
if (m == 1) {
|
||||
/* current[] = current[] XOR polys[poly].poly_mul[]*/
|
||||
ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize ocb->Offset_current = Offset_0 */
|
||||
s_ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen);
|
||||
|
||||
/* initialize checksum to all zeros */
|
||||
zeromem(ocb->checksum, ocb->block_len);
|
||||
|
||||
/* set block index */
|
||||
ocb->block_index = 1;
|
||||
|
||||
/* initialize AAD related stuff */
|
||||
ocb->ablock_index = 1;
|
||||
ocb->adata_buffer_bytes = 0;
|
||||
zeromem(ocb->aOffset_current, ocb->block_len);
|
||||
zeromem(ocb->aSum_current, ocb->block_len);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
29
deps/libtomcrypt/src/encauth/ocb3/ocb3_int_ntz.c
vendored
Normal file
29
deps/libtomcrypt/src/encauth/ocb3/ocb3_int_ntz.c
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_int_ntz.c
|
||||
OCB implementation, INTERNAL ONLY helper, by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Returns the number of leading zero bits [from lsb up] (internal function)
|
||||
@param x The 32-bit value to observe
|
||||
@return The number of bits [from the lsb up] that are zero
|
||||
*/
|
||||
int ocb3_int_ntz(unsigned long x)
|
||||
{
|
||||
int c;
|
||||
x &= 0xFFFFFFFFUL;
|
||||
c = 0;
|
||||
while ((x & 1) == 0) {
|
||||
++c;
|
||||
x >>= 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
30
deps/libtomcrypt/src/encauth/ocb3/ocb3_int_xor_blocks.c
vendored
Normal file
30
deps/libtomcrypt/src/encauth/ocb3/ocb3_int_xor_blocks.c
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_int_xor_blocks.c
|
||||
OCB implementation, INTERNAL ONLY helper, by Karel Miko
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Compute xor for two blocks of bytes 'out = block_a XOR block_b' (internal function)
|
||||
@param out The block of bytes (output)
|
||||
@param block_a The block of bytes (input)
|
||||
@param block_b The block of bytes (input)
|
||||
@param block_len The size of block_a, block_b, out
|
||||
*/
|
||||
void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len)
|
||||
{
|
||||
int x;
|
||||
if (out == block_a) {
|
||||
for (x = 0; x < (int)block_len; x++) out[x] ^= block_b[x];
|
||||
}
|
||||
else {
|
||||
for (x = 0; x < (int)block_len; x++) out[x] = block_a[x] ^ block_b[x];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
299
deps/libtomcrypt/src/encauth/ocb3/ocb3_test.c
vendored
Normal file
299
deps/libtomcrypt/src/encauth/ocb3/ocb3_test.c
vendored
Normal file
@ -0,0 +1,299 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
/**
|
||||
@file ocb3_test.c
|
||||
OCB implementation, self-test by Tom St Denis
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_OCB3_MODE
|
||||
|
||||
/**
|
||||
Test the OCB protocol
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ocb3_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
/* test vectors from: http://tools.ietf.org/html/draft-krovetz-ocb-03 */
|
||||
unsigned char key[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F };
|
||||
unsigned char nonce[12] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B };
|
||||
const struct {
|
||||
int ptlen;
|
||||
int aadlen;
|
||||
unsigned char pt[64], aad[64], ct[64], tag[16];
|
||||
} tests[] = {
|
||||
|
||||
{ /* index:0 */
|
||||
0, /* PLAINTEXT length */
|
||||
0, /* AAD length */
|
||||
{ 0 }, /* PLAINTEXT */
|
||||
{ 0 }, /* AAD */
|
||||
{ 0 }, /* CIPHERTEXT */
|
||||
{ 0x19,0x7b,0x9c,0x3c,0x44,0x1d,0x3c,0x83,0xea,0xfb,0x2b,0xef,0x63,0x3b,0x91,0x82 }, /* TAG */
|
||||
},
|
||||
{ /* index:1 */
|
||||
8, /* PLAINTEXT length */
|
||||
8, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* AAD */
|
||||
{ 0x92,0xb6,0x57,0x13,0x0a,0x74,0xb8,0x5a }, /* CIPHERTEXT */
|
||||
{ 0x16,0xdc,0x76,0xa4,0x6d,0x47,0xe1,0xea,0xd5,0x37,0x20,0x9e,0x8a,0x96,0xd1,0x4e }, /* TAG */
|
||||
},
|
||||
{ /* index:2 */
|
||||
0, /* PLAINTEXT length */
|
||||
8, /* AAD length */
|
||||
{ 0 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* AAD */
|
||||
{ 0 }, /* CIPHERTEXT */
|
||||
{ 0x98,0xb9,0x15,0x52,0xc8,0xc0,0x09,0x18,0x50,0x44,0xe3,0x0a,0x6e,0xb2,0xfe,0x21 }, /* TAG */
|
||||
},
|
||||
{ /* index:3 */
|
||||
8, /* PLAINTEXT length */
|
||||
0, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* PLAINTEXT */
|
||||
{ 0 }, /* AAD */
|
||||
{ 0x92,0xb6,0x57,0x13,0x0a,0x74,0xb8,0x5a }, /* CIPHERTEXT */
|
||||
{ 0x97,0x1e,0xff,0xca,0xe1,0x9a,0xd4,0x71,0x6f,0x88,0xe8,0x7b,0x87,0x1f,0xbe,0xed }, /* TAG */
|
||||
},
|
||||
{ /* index:4 */
|
||||
16, /* PLAINTEXT length */
|
||||
16, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22 }, /* CIPHERTEXT */
|
||||
{ 0x77,0x6c,0x99,0x24,0xd6,0x72,0x3a,0x1f,0xc4,0x52,0x45,0x32,0xac,0x3e,0x5b,0xeb }, /* TAG */
|
||||
},
|
||||
{ /* index:5 */
|
||||
0, /* PLAINTEXT length */
|
||||
16, /* AAD length */
|
||||
{ 0 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* AAD */
|
||||
{ 0 }, /* CIPHERTEXT */
|
||||
{ 0x7d,0xdb,0x8e,0x6c,0xea,0x68,0x14,0x86,0x62,0x12,0x50,0x96,0x19,0xb1,0x9c,0xc6 }, /* TAG */
|
||||
},
|
||||
{ /* index:6 */
|
||||
16, /* PLAINTEXT length */
|
||||
0, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* PLAINTEXT */
|
||||
{ 0 }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22 }, /* CIPHERTEXT */
|
||||
{ 0x13,0xcc,0x8b,0x74,0x78,0x07,0x12,0x1a,0x4c,0xbb,0x3e,0x4b,0xd6,0xb4,0x56,0xaf }, /* TAG */
|
||||
},
|
||||
{ /* index:7 */
|
||||
24, /* PLAINTEXT length */
|
||||
24, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xfc,0xfc,0xee,0x7a,0x2a,0x8d,0x4d,0x48 }, /* CIPHERTEXT */
|
||||
{ 0x5f,0xa9,0x4f,0xc3,0xf3,0x88,0x20,0xf1,0xdc,0x3f,0x3d,0x1f,0xd4,0xe5,0x5e,0x1c }, /* TAG */
|
||||
},
|
||||
{ /* index:8 */
|
||||
0, /* PLAINTEXT length */
|
||||
24, /* AAD length */
|
||||
{ 0 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* AAD */
|
||||
{ 0 }, /* CIPHERTEXT */
|
||||
{ 0x28,0x20,0x26,0xda,0x30,0x68,0xbc,0x9f,0xa1,0x18,0x68,0x1d,0x55,0x9f,0x10,0xf6 }, /* TAG */
|
||||
},
|
||||
{ /* index:9 */
|
||||
24, /* PLAINTEXT length */
|
||||
0, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* PLAINTEXT */
|
||||
{ 0 }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xfc,0xfc,0xee,0x7a,0x2a,0x8d,0x4d,0x48 }, /* CIPHERTEXT */
|
||||
{ 0x6e,0xf2,0xf5,0x25,0x87,0xfd,0xa0,0xed,0x97,0xdc,0x7e,0xed,0xe2,0x41,0xdf,0x68 }, /* TAG */
|
||||
},
|
||||
{ /* index:10 */
|
||||
32, /* PLAINTEXT length */
|
||||
32, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb }, /* CIPHERTEXT */
|
||||
{ 0xb2,0xa0,0x40,0xdd,0x3b,0xd5,0x16,0x43,0x72,0xd7,0x6d,0x7b,0xb6,0x82,0x42,0x40 }, /* TAG */
|
||||
},
|
||||
{ /* index:11 */
|
||||
0, /* PLAINTEXT length */
|
||||
32, /* AAD length */
|
||||
{ 0 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* AAD */
|
||||
{ 0 }, /* CIPHERTEXT */
|
||||
{ 0xe1,0xe0,0x72,0x63,0x3b,0xad,0xe5,0x1a,0x60,0xe8,0x59,0x51,0xd9,0xc4,0x2a,0x1b }, /* TAG */
|
||||
},
|
||||
{ /* index:12 */
|
||||
32, /* PLAINTEXT length */
|
||||
0, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* PLAINTEXT */
|
||||
{ 0 }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb }, /* CIPHERTEXT */
|
||||
{ 0x4a,0x3b,0xae,0x82,0x44,0x65,0xcf,0xda,0xf8,0xc4,0x1f,0xc5,0x0c,0x7d,0xf9,0xd9 }, /* TAG */
|
||||
},
|
||||
{ /* index:13 */
|
||||
40, /* PLAINTEXT length */
|
||||
40, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb,0x68,0xc6,0x57,0x78,0xb0,0x58,0xa6,0x35 }, /* CIPHERTEXT */
|
||||
{ 0x65,0x9c,0x62,0x32,0x11,0xde,0xea,0x0d,0xe3,0x0d,0x2c,0x38,0x18,0x79,0xf4,0xc8 }, /* TAG */
|
||||
},
|
||||
{ /* index:14 */
|
||||
0, /* PLAINTEXT length */
|
||||
40, /* AAD length */
|
||||
{ 0 }, /* PLAINTEXT */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* AAD */
|
||||
{ 0 }, /* CIPHERTEXT */
|
||||
{ 0x7a,0xeb,0x7a,0x69,0xa1,0x68,0x7d,0xd0,0x82,0xca,0x27,0xb0,0xd9,0xa3,0x70,0x96 }, /* TAG */
|
||||
},
|
||||
{ /* index:15 */
|
||||
40, /* PLAINTEXT length */
|
||||
0, /* AAD length */
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* PLAINTEXT */
|
||||
{ 0 }, /* AAD */
|
||||
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb,0x68,0xc6,0x57,0x78,0xb0,0x58,0xa6,0x35 }, /* CIPHERTEXT */
|
||||
{ 0x06,0x0c,0x84,0x67,0xf4,0xab,0xab,0x5e,0x8b,0x3c,0x20,0x67,0xa2,0xe1,0x15,0xdc }, /* TAG */
|
||||
},
|
||||
|
||||
};
|
||||
/* As of RFC 7253 - 'Appendix A. Sample Results'
|
||||
* The next tuple shows a result with a tag length of 96 bits and a
|
||||
different key.
|
||||
|
||||
K: 0F0E0D0C0B0A09080706050403020100
|
||||
|
||||
N: BBAA9988776655443322110D
|
||||
A: 000102030405060708090A0B0C0D0E0F1011121314151617
|
||||
18191A1B1C1D1E1F2021222324252627
|
||||
P: 000102030405060708090A0B0C0D0E0F1011121314151617
|
||||
18191A1B1C1D1E1F2021222324252627
|
||||
C: 1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1
|
||||
A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD
|
||||
AC4F02AA
|
||||
|
||||
The C has been split up in C and T (tag)
|
||||
*/
|
||||
const unsigned char K[] = { 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,
|
||||
0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 };
|
||||
const unsigned char N[] = { 0xBB,0xAA,0x99,0x88,0x77,0x66,0x55,0x44,
|
||||
0x33,0x22,0x11,0x0D };
|
||||
const unsigned char A[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 };
|
||||
const unsigned char P[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 };
|
||||
const unsigned char C[] = { 0x17,0x92,0xA4,0xE3,0x1E,0x07,0x55,0xFB,
|
||||
0x03,0xE3,0x1B,0x22,0x11,0x6E,0x6C,0x2D,
|
||||
0xDF,0x9E,0xFD,0x6E,0x33,0xD5,0x36,0xF1,
|
||||
0xA0,0x12,0x4B,0x0A,0x55,0xBA,0xE8,0x84,
|
||||
0xED,0x93,0x48,0x15,0x29,0xC7,0x6B,0x6A };
|
||||
const unsigned char T[] = { 0xD0,0xC5,0x15,0xF4,0xD1,0xCD,0xD4,0xFD,
|
||||
0xAC,0x4F,0x02,0xAA };
|
||||
|
||||
int err, x, idx, res;
|
||||
unsigned long len;
|
||||
unsigned char outct[MAXBLOCKSIZE] = { 0 };
|
||||
unsigned char outtag[MAXBLOCKSIZE] = { 0 };
|
||||
ocb3_state ocb;
|
||||
|
||||
/* AES can be under rijndael or aes... try to find it */
|
||||
if ((idx = find_cipher("aes")) == -1) {
|
||||
if ((idx = find_cipher("rijndael")) == -1) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
len = 16; /* must be the same as the required taglen */
|
||||
if ((err = ocb3_encrypt_authenticate_memory(idx,
|
||||
key, sizeof(key),
|
||||
nonce, sizeof(nonce),
|
||||
tests[x].aadlen != 0 ? tests[x].aad : NULL, tests[x].aadlen,
|
||||
tests[x].ptlen != 0 ? tests[x].pt : NULL, tests[x].ptlen,
|
||||
tests[x].ptlen != 0 ? outct : NULL, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (compare_testvector(outtag, len, tests[x].tag, sizeof(tests[x].tag), "OCB3 Tag", x) ||
|
||||
compare_testvector(outct, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "OCB3 CT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((err = ocb3_decrypt_verify_memory(idx,
|
||||
key, sizeof(key),
|
||||
nonce, sizeof(nonce),
|
||||
tests[x].aadlen != 0 ? tests[x].aad : NULL, tests[x].aadlen,
|
||||
tests[x].ptlen != 0 ? outct : NULL, tests[x].ptlen,
|
||||
tests[x].ptlen != 0 ? outct : NULL, tests[x].tag, len, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || compare_testvector(outct, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "OCB3", x)) {
|
||||
#ifdef LTC_TEST_DBG
|
||||
printf("\n\nOCB3: Failure-decrypt - res = %d\n", res);
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC 7253 - test vector with a tag length of 96 bits - part 1 */
|
||||
x = 99;
|
||||
len = 12;
|
||||
if ((err = ocb3_encrypt_authenticate_memory(idx,
|
||||
K, sizeof(K),
|
||||
N, sizeof(N),
|
||||
A, sizeof(A),
|
||||
P, sizeof(P),
|
||||
outct, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag", x) ||
|
||||
compare_testvector(outct, sizeof(P), C, sizeof(C), "OCB3 CT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((err = ocb3_decrypt_verify_memory(idx,
|
||||
K, sizeof(K),
|
||||
N, sizeof(N),
|
||||
A, sizeof(A),
|
||||
C, sizeof(C),
|
||||
outct, T, sizeof(T), &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || compare_testvector(outct, sizeof(C), P, sizeof(P), "OCB3", x)) {
|
||||
#ifdef LTC_TEST_DBG
|
||||
printf("\n\nOCB3: Failure-decrypt - res = %d\n", res);
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* RFC 7253 - test vector with a tag length of 96 bits - part 2 */
|
||||
x = 100;
|
||||
if ((err = ocb3_init(&ocb, idx, K, sizeof(K), N, sizeof(N), 12)) != CRYPT_OK) return err;
|
||||
if ((err = ocb3_add_aad(&ocb, A, sizeof(A))) != CRYPT_OK) return err;
|
||||
if ((err = ocb3_encrypt(&ocb, P, 32, outct)) != CRYPT_OK) return err;
|
||||
if ((err = ocb3_encrypt_last(&ocb, P+32, sizeof(P)-32, outct+32)) != CRYPT_OK) return err;
|
||||
len = sizeof(outtag); /* intentionally more than 12 */
|
||||
if ((err = ocb3_done(&ocb, outtag, &len)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(outct, sizeof(P), C, sizeof(C), "OCB3 CT", x)) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag.enc", x)) return CRYPT_FAIL_TESTVECTOR;
|
||||
if ((err = ocb3_init(&ocb, idx, K, sizeof(K), N, sizeof(N), 12)) != CRYPT_OK) return err;
|
||||
if ((err = ocb3_add_aad(&ocb, A, sizeof(A))) != CRYPT_OK) return err;
|
||||
if ((err = ocb3_decrypt(&ocb, C, 32, outct)) != CRYPT_OK) return err;
|
||||
if ((err = ocb3_decrypt_last(&ocb, C+32, sizeof(C)-32, outct+32)) != CRYPT_OK) return err;
|
||||
len = sizeof(outtag); /* intentionally more than 12 */
|
||||
if ((err = ocb3_done(&ocb, outtag, &len)) != CRYPT_OK) return err;
|
||||
if (compare_testvector(outct, sizeof(C), P, sizeof(P), "OCB3 PT", x)) return CRYPT_FAIL_TESTVECTOR;
|
||||
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag.dec", x)) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif /* LTC_TEST */
|
||||
}
|
||||
|
||||
#endif /* LTC_OCB3_MODE */
|
Reference in New Issue
Block a user