added libtomcrypt-1.00

This commit is contained in:
Tom St Denis
2004-12-30 23:55:53 +00:00
committed by Steffen Jaeckel
parent 1c1822d510
commit bfc2f5b078
257 changed files with 12657 additions and 5352 deletions
+34
View File
@@ -0,0 +1,34 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_addheader.c
EAX implementation, add meta-data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+46
View File
@@ -0,0 +1,46 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_decrypt.c
EAX implementation, decrypt block, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+104
View File
@@ -0,0 +1,104 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_decrypt_verify_memory.c
EAX implementation, decrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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,
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;
/* 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 && memcmp(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
+85
View File
@@ -0,0 +1,85 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_done.c
EAX implementation, terminate session, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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;
}
/* 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
+47
View File
@@ -0,0 +1,47 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_encrypt.c
EAX implementation, encrypt block by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
@@ -0,0 +1,78 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_encrypt_authenticate_memory.c
EAX implementation, encrypt a block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+142
View File
@@ -0,0 +1,142 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_init.c
EAX implementation, initialized EAX state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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 = 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 = 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, &eax->ctr)) != CRYPT_OK) {
goto LBL_ERR;
}
/* use big-endian counter */
eax->ctr.mode = 1;
/* setup the 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
+278
View File
@@ -0,0 +1,278 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file eax_test.c
EAX implementation, self-test, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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 (memcmp(outct, tests[x].ciphertext, tests[x].msglen) || memcmp(outtag, tests[x].tag, len)) {
#if 0
unsigned long y;
printf("\n\nFailure: \nCT:\n");
for (y = 0; y < (unsigned long)tests[x].msglen; ) {
printf("0x%02x", outct[y]);
if (y < (unsigned long)(tests[x].msglen-1)) printf(", ");
if (!(++y % 8)) printf("\n");
}
printf("\nTAG:\n");
for (y = 0; y < len; ) {
printf("0x%02x", outtag[y]);
if (y < len-1) printf(", ");
if (!(++y % 8)) printf("\n");
}
#endif
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) || memcmp(outct, tests[x].plaintext, tests[x].msglen)) {
#if 0
unsigned long y;
printf("\n\nFailure (res == %d): \nPT:\n", res);
for (y = 0; y < (unsigned long)tests[x].msglen; ) {
printf("0x%02x", outct[y]);
if (y < (unsigned long)(tests[x].msglen-1)) printf(", ");
if (!(++y % 8)) printf("\n");
}
printf("\n\n");
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif /* LTC_TEST */
}
#endif /* EAX_MODE */
+73
View File
@@ -0,0 +1,73 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_decrypt.c
OCB implementation, decrypt data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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];
}
cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key);
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
@@ -0,0 +1,82 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_decrypt_verify_memory.c
OCB implementation, helper to decrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+76
View File
@@ -0,0 +1,76 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_done_decrypt.c
OCB implementation, terminate decryption, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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 && memcmp(tagbuf, tag, taglen) == 0) {
*stat = 1;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(tagbuf, MAXBLOCKSIZE);
#endif
XFREE(tagbuf);
return err;
}
#endif
+42
View File
@@ -0,0 +1,42 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_done_encrypt.c
OCB implementation, terminate encryption, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+66
View File
@@ -0,0 +1,66 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_encrypt.c
OCB implementation, encrypt data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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];
}
cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key);
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
@@ -0,0 +1,80 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_encrypt_authenticate_memory.c
OCB implementation, encrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
View File
@@ -0,0 +1,129 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_init.c
OCB implementation, initialize state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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;
for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
if (polys[poly].len == ocb->block_len) {
break;
}
}
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);
cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key);
/* find R = E[N xor L] */
for (x = 0; x < ocb->block_len; x++) {
ocb->R[x] = ocb->L[x] ^ nonce[x];
}
cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key);
/* 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
+38
View File
@@ -0,0 +1,38 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_ntz.c
OCB implementation, internal function, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+35
View File
@@ -0,0 +1,35 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_shift_xor.c
OCB implementation, internal function, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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
+233
View File
@@ -0,0 +1,233 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file ocb_test.c
OCB implementation, self-test by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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 (memcmp(outtag, tests[x].tag, len) || memcmp(outct, tests[x].ct, tests[x].ptlen)) {
#if 0
unsigned long y;
printf("\n\nFailure: \nCT:\n");
for (y = 0; y < (unsigned long)tests[x].ptlen; ) {
printf("0x%02x", outct[y]);
if (y < (unsigned long)(tests[x].ptlen-1)) printf(", ");
if (!(++y % 8)) printf("\n");
}
printf("\nTAG:\n");
for (y = 0; y < len; ) {
printf("0x%02x", outtag[y]);
if (y < len-1) printf(", ");
if (!(++y % 8)) printf("\n");
}
#endif
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) || memcmp(tests[x].pt, outct, tests[x].ptlen)) {
#if 0
unsigned long y;
printf("\n\nFailure-decrypt: \nPT:\n");
for (y = 0; y < (unsigned long)tests[x].ptlen; ) {
printf("0x%02x", outct[y]);
if (y < (unsigned long)(tests[x].ptlen-1)) printf(", ");
if (!(++y % 8)) printf("\n");
}
printf("\nres = %d\n\n", res);
#endif
}
}
return CRYPT_OK;
#endif /* LTC_TEST */
}
#endif /* 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...
*/
+139
View File
@@ -0,0 +1,139 @@
/* 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@iahu.ca, http://libtomcrypt.org
*/
/**
@file s_ocb_done.c
OCB implementation, internal helper, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef 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])) */
cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key);
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!! */
cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &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
XFREE(X);
XFREE(Y);
XFREE(Z);
return CRYPT_OK;
}
#endif