Remove ccm_memory_ex()
This commit is contained in:
parent
363a57fc87
commit
8af93d1d0d
@ -1,383 +0,0 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ccm_memory.c
|
||||
CCM support, process a block of memory, Tom St Denis
|
||||
*/
|
||||
|
||||
#if defined LTC_CCM_MODE && 0
|
||||
|
||||
/**
|
||||
CCM encrypt/decrypt 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 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 [out] 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
|
||||
@param direction Encrypt or Decrypt direction (0 or 1)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ccm_memory_ex(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,
|
||||
const unsigned char *B_0,
|
||||
const unsigned char *CTR,
|
||||
int ctrwidth)
|
||||
{
|
||||
unsigned char PAD[16], ctr[16], CTRPAD[16], ctrcopy[16], b;
|
||||
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);
|
||||
|
||||
#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 even and <= 16 */
|
||||
*taglen &= ~1;
|
||||
if (*taglen > 16) {
|
||||
*taglen = 16;
|
||||
}
|
||||
|
||||
/* can't use < 4 */
|
||||
if (*taglen < 4) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* decrease noncelen to match L */
|
||||
if ((noncelen + L) > 15) {
|
||||
noncelen = 15 - L;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* form B_0 == flags | Nonce N | l(m) */
|
||||
x = 0;
|
||||
|
||||
if (B_0 == NULL) {
|
||||
PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
|
||||
(((*taglen - 2)>>1)<<3) |
|
||||
(L-1));
|
||||
|
||||
/* nonce */
|
||||
for (y = 0; y < (16 - (L + 1)); 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;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* B_0 != NULL */
|
||||
XMEMCPY(PAD, B_0, 16);
|
||||
}
|
||||
|
||||
/* encrypt PAD */
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* handle header */
|
||||
if (headerlen > 0) {
|
||||
x = 0;
|
||||
|
||||
#if 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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 (x != 0) {
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* setup the ctr counter */
|
||||
if (CTR == NULL) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
XMEMCPY(ctr, CTR, 16);
|
||||
}
|
||||
|
||||
x = 0;
|
||||
CTRlen = 16;
|
||||
|
||||
/* now handle the PT */
|
||||
if (ptlen > 0) {
|
||||
y = 0;
|
||||
#ifdef LTC_FAST2
|
||||
if (ptlen & ~15) {
|
||||
if (direction == CCM_ENCRYPT) {
|
||||
for (; y < (ptlen & ~15); y += 16) {
|
||||
/* increment the ctr? */
|
||||
for (z = 15; (int)z > (int)(15-ctrwidth); 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 {
|
||||
for (; y < (ptlen & ~15); y += 16) {
|
||||
/* increment the ctr? */
|
||||
for (z = 15; (int)z > (int)(15-ctrwidth); 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; (int)z > (int)(15-ctrwidth); 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* grab the CTR */
|
||||
XMEMCPY(ctrcopy, ctr, 16);
|
||||
|
||||
/* setup CTR for the TAG (zero the count) */
|
||||
if (CTR == NULL) {
|
||||
for (y = 15; y > 15 - L; y--) {
|
||||
ctr[y] = 0x00;
|
||||
}
|
||||
} else {
|
||||
XMEMCPY(ctr, CTR, 16);
|
||||
}
|
||||
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (skey != uskey) {
|
||||
cipher_descriptor[cipher].done(skey);
|
||||
}
|
||||
|
||||
/* store the TAG */
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
tag[x] = PAD[x] ^ CTRPAD[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
if (CTR != NULL) {
|
||||
for (z = 15; (int)z > (int)(15-ctrwidth); z--) {
|
||||
ctrcopy[z] = (ctrcopy[z] + 1) & 255;
|
||||
if (ctrcopy[z]) break;
|
||||
}
|
||||
XMEMCPY(CTR, ctrcopy, 16);
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(skey, sizeof(*skey));
|
||||
zeromem(PAD, sizeof(PAD));
|
||||
zeromem(CTRPAD, sizeof(CTRPAD));
|
||||
#endif
|
||||
error:
|
||||
if (skey != uskey) {
|
||||
XFREE(skey);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
@ -307,19 +307,6 @@ int ccm_memory(int cipher,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
|
||||
int ccm_memory_ex(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,
|
||||
const unsigned char *B_0,
|
||||
const unsigned char *CTR,
|
||||
int ctrwidth);
|
||||
|
||||
int ccm_test(void);
|
||||
|
||||
#endif /* LTC_CCM_MODE */
|
||||
|
Loading…
Reference in New Issue
Block a user