OCBv3 according http://tools.ietf.org/html/draft-krovetz-ocb-03
This commit is contained in:
parent
8e22b17a8e
commit
abab7089a3
@ -516,6 +516,68 @@ void ocb_gen(void)
|
|||||||
fclose(out);
|
fclose(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ocb3_gen(void)
|
||||||
|
{
|
||||||
|
int err, kl, x, y1, z;
|
||||||
|
FILE *out;
|
||||||
|
unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
|
||||||
|
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
|
||||||
|
unsigned long len;
|
||||||
|
|
||||||
|
out = fopen("ocb3_tv.txt", "w");
|
||||||
|
fprintf(out, "OCB3 Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n"
|
||||||
|
"are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n"
|
||||||
|
"step repeated sufficiently. The nonce is fixed throughout. AAD is fixed to 3 bytes (ASCII) 'AAD'.\n\n");
|
||||||
|
|
||||||
|
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||||
|
kl = cipher_descriptor[x].block_length;
|
||||||
|
|
||||||
|
/* skip ciphers which do not have 64 or 128 bit block sizes */
|
||||||
|
if (kl != 8 && kl != 16) continue;
|
||||||
|
|
||||||
|
if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
|
||||||
|
kl = cipher_descriptor[x].max_key_length;
|
||||||
|
}
|
||||||
|
fprintf(out, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
|
||||||
|
|
||||||
|
/* the key */
|
||||||
|
for (z = 0; z < kl; z++) {
|
||||||
|
key[z] = (z & 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixed nonce */
|
||||||
|
for (z = 0; z < cipher_descriptor[x].block_length; z++) {
|
||||||
|
nonce[z] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
|
||||||
|
for (z = 0; z < y1; z++) {
|
||||||
|
plaintext[z] = (unsigned char)(z & 255);
|
||||||
|
}
|
||||||
|
len = sizeof(tag);
|
||||||
|
if ((err = ocb3_encrypt_authenticate_memory(x, key, kl, nonce, cipher_descriptor[x].block_length, "AAD", 3, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
|
||||||
|
printf("Error OCB'ing: %s\n", error_to_string(err));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
fprintf(out, "%3d: ", y1);
|
||||||
|
for (z = 0; z < y1; z++) {
|
||||||
|
fprintf(out, "%02X", plaintext[z]);
|
||||||
|
}
|
||||||
|
fprintf(out, ", ");
|
||||||
|
for (z = 0; z <(int)len; z++) {
|
||||||
|
fprintf(out, "%02X", tag[z]);
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
|
||||||
|
/* forward the key */
|
||||||
|
for (z = 0; z < kl; z++) {
|
||||||
|
key[z] = tag[z % len];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
|
fclose(out);
|
||||||
|
}
|
||||||
|
|
||||||
void ccm_gen(void)
|
void ccm_gen(void)
|
||||||
{
|
{
|
||||||
@ -775,6 +837,7 @@ int main(void)
|
|||||||
printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n");
|
printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n");
|
||||||
printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n");
|
printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n");
|
||||||
printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n");
|
printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n");
|
||||||
|
printf("Generating OCB3 vectors..."); fflush(stdout); ocb3_gen(); printf("done\n");
|
||||||
printf("Generating CCM vectors..."); fflush(stdout); ccm_gen(); printf("done\n");
|
printf("Generating CCM vectors..."); fflush(stdout); ccm_gen(); printf("done\n");
|
||||||
printf("Generating GCM vectors..."); fflush(stdout); gcm_gen(); printf("done\n");
|
printf("Generating GCM vectors..."); fflush(stdout); gcm_gen(); printf("done\n");
|
||||||
printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n");
|
printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n");
|
||||||
|
81
src/encauth/ocb3/ocb3_add_aad.c
Normal file
81
src/encauth/ocb3/ocb3_add_aad.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_add_aad.c
|
||||||
|
OCB implementation, add AAD data, by Karel Miko
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.h"
|
||||||
|
|
||||||
|
#ifdef LTC_OCB3_MODE
|
||||||
|
|
||||||
|
/**
|
||||||
|
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);
|
||||||
|
LTC_ARGCHK(aad != NULL);
|
||||||
|
|
||||||
|
if (aadlen == 0) return CRYPT_OK;
|
||||||
|
|
||||||
|
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 = 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 = 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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
86
src/encauth/ocb3/ocb3_decrypt.c
Normal file
86
src/encauth/ocb3/ocb3_decrypt.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_decrypt.c
|
||||||
|
OCB implementation, decrypt data, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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);
|
||||||
|
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 (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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
106
src/encauth/ocb3/ocb3_decrypt_last.c
Normal file
106
src/encauth/ocb3/ocb3_decrypt_last.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_decrypt_last.c
|
||||||
|
OCB implementation, internal helper, by Karel Miko
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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);
|
||||||
|
LTC_ARGCHK(ct != 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);
|
||||||
|
zeromem(ocb, sizeof(*ocb));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
112
src/encauth/ocb3/ocb3_decrypt_verify_memory.c
Normal file
112
src/encauth/ocb3/ocb3_decrypt_verify_memory.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_decrypt_verify_memory.c
|
||||||
|
OCB implementation, helper to decrypt block of memory, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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(key != NULL);
|
||||||
|
LTC_ARGCHK(nonce != NULL);
|
||||||
|
LTC_ARGCHK(pt != NULL);
|
||||||
|
LTC_ARGCHK(ct != NULL);
|
||||||
|
LTC_ARGCHK(tag != NULL);
|
||||||
|
LTC_ARGCHK(stat != NULL);
|
||||||
|
|
||||||
|
/* default to zero */
|
||||||
|
*stat = 0;
|
||||||
|
|
||||||
|
/* 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)) != CRYPT_OK) {
|
||||||
|
goto LBL_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 && XMEMCMP(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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
92
src/encauth/ocb3/ocb3_done.c
Normal file
92
src/encauth/ocb3/ocb3_done.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_done.c
|
||||||
|
OCB implementation, INTERNAL ONLY helper, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* fix taglen if needed */
|
||||||
|
if ((int)*taglen > ocb->block_len) {
|
||||||
|
*taglen = (unsigned long)ocb->block_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy tag bytes */
|
||||||
|
for(x=0; x<(int)*taglen; x++) tag[x] = tmp[x];
|
||||||
|
|
||||||
|
err = CRYPT_OK;
|
||||||
|
|
||||||
|
LBL_ERR:
|
||||||
|
#ifdef LTC_CLEAN_STACK
|
||||||
|
zeromem(tmp, MAXBLOCKSIZE);
|
||||||
|
zeromem(ocb, sizeof(*ocb));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
86
src/encauth/ocb3/ocb3_encrypt.c
Normal file
86
src/encauth/ocb3/ocb3_encrypt.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_encrypt.c
|
||||||
|
OCB implementation, encrypt data, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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);
|
||||||
|
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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
87
src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
Normal file
87
src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_encrypt_authenticate_memory.c
|
||||||
|
OCB implementation, encrypt block of memory, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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(key != NULL);
|
||||||
|
LTC_ARGCHK(nonce != NULL);
|
||||||
|
LTC_ARGCHK(pt != NULL);
|
||||||
|
LTC_ARGCHK(ct != NULL);
|
||||||
|
LTC_ARGCHK(tag != NULL);
|
||||||
|
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)) != CRYPT_OK) {
|
||||||
|
goto LBL_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
108
src/encauth/ocb3/ocb3_encrypt_last.c
Normal file
108
src/encauth/ocb3/ocb3_encrypt_last.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_encrypt_last.c
|
||||||
|
OCB implementation, internal helper, by Karel Miko
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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);
|
||||||
|
LTC_ARGCHK(pt != 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);
|
||||||
|
zeromem(ocb, sizeof(*ocb));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
134
src/encauth/ocb3/ocb3_init.c
Normal file
134
src/encauth/ocb3/ocb3_init.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_init.c
|
||||||
|
OCB implementation, initialize state, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.h"
|
||||||
|
|
||||||
|
#ifdef LTC_OCB3_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
|
||||||
|
@param noncelen The length of the session nonce (octets)
|
||||||
|
@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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
ocb3_int_calc_offset_zero(ocb, nonce, noncelen);
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
49
src/encauth/ocb3/ocb3_int_aad_add_block.c
Normal file
49
src/encauth/ocb3/ocb3_int_aad_add_block.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_int_aad_add_block.c
|
||||||
|
OCB implementation, INTERNALL ONLY helper, by Karel Miko
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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
|
||||||
|
*/
|
||||||
|
int 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
72
src/encauth/ocb3/ocb3_int_calc_offset_zero.c
Normal file
72
src/encauth/ocb3/ocb3_int_calc_offset_zero.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_int_calc_offset_zero.c
|
||||||
|
OCB implementation, INTERNAL ONLY helper, by Karel Miko
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.h"
|
||||||
|
|
||||||
|
#ifdef LTC_OCB3_MODE
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets 'ocb->Offset_current' to 'Offset_0' value (internal function)
|
||||||
|
@param ocb The OCB state
|
||||||
|
@param nonce The session nonce
|
||||||
|
@param noncelen The length of the session nonce (octets)
|
||||||
|
*/
|
||||||
|
void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
41
src/encauth/ocb3/ocb3_int_ntz.c
Normal file
41
src/encauth/ocb3/ocb3_int_ntz.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_int_ntz.c
|
||||||
|
OCB implementation, INTERNAL ONLY helper, by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
40
src/encauth/ocb3/ocb3_int_xor_blocks.c
Normal file
40
src/encauth/ocb3/ocb3_int_xor_blocks.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_int_xor_blocks.c
|
||||||
|
OCB implementation, INTERNAL ONLY helper, by Karel Miko
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
246
src/encauth/ocb3/ocb3_test.c
Normal file
246
src/encauth/ocb3/ocb3_test.c
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file ocb3_test.c
|
||||||
|
OCB implementation, self-test by Tom St Denis
|
||||||
|
*/
|
||||||
|
#include "tomcrypt.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 };
|
||||||
|
static 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 */
|
||||||
|
{ }, /* PLAINTEXT */
|
||||||
|
{ }, /* AAD */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* PLAINTEXT */
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* AAD */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* PLAINTEXT */
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* AAD */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
{ }, /* 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 */
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = ocb3_encrypt_authenticate_memory(idx,
|
||||||
|
key, sizeof(key),
|
||||||
|
nonce, sizeof(nonce),
|
||||||
|
tests[x].aad, tests[x].aadlen,
|
||||||
|
tests[x].pt, tests[x].ptlen,
|
||||||
|
outct, outtag, &len)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XMEMCMP(outtag, tests[x].tag, len) || XMEMCMP(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 = ocb3_decrypt_verify_memory(idx,
|
||||||
|
key, sizeof(key),
|
||||||
|
nonce, sizeof(nonce),
|
||||||
|
tests[x].aad, tests[x].aadlen,
|
||||||
|
outct, tests[x].ptlen,
|
||||||
|
outct, tests[x].tag, len, &res)) != CRYPT_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if ((res != 1) || XMEMCMP(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 /* LTC_OCB3_MODE */
|
||||||
|
|
||||||
|
/* some comments
|
||||||
|
|
||||||
|
-- it's hard to seek
|
||||||
|
-- hard to stream [you can't emit ciphertext until full block]
|
||||||
|
-- The setup is somewhat complicated...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Source$ */
|
||||||
|
/* $Revision$ */
|
||||||
|
/* $Date$ */
|
@ -231,6 +231,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LTC_OCB_MODE
|
#define LTC_OCB_MODE
|
||||||
|
#define LTC_OCB3_MODE
|
||||||
#define LTC_CCM_MODE
|
#define LTC_CCM_MODE
|
||||||
#define LTC_GCM_MODE
|
#define LTC_GCM_MODE
|
||||||
|
|
||||||
|
@ -193,6 +193,67 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
|||||||
|
|
||||||
#endif /* LTC_OCB_MODE */
|
#endif /* LTC_OCB_MODE */
|
||||||
|
|
||||||
|
#ifdef LTC_OCB3_MODE
|
||||||
|
typedef struct {
|
||||||
|
unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */
|
||||||
|
Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */
|
||||||
|
L_dollar[MAXBLOCKSIZE], /* L_$ value */
|
||||||
|
L_star[MAXBLOCKSIZE], /* L_* value */
|
||||||
|
L_[32][MAXBLOCKSIZE], /* L_{i} values */
|
||||||
|
tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */
|
||||||
|
checksum[MAXBLOCKSIZE]; /* current checksum */
|
||||||
|
|
||||||
|
/* AAD related members */
|
||||||
|
unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
|
||||||
|
aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
|
||||||
|
adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
|
||||||
|
int adata_buffer_bytes; /* bytes in AAD buffer */
|
||||||
|
unsigned long ablock_index; /* index # for current adata (AAD) block */
|
||||||
|
|
||||||
|
symmetric_key key; /* scheduled key for cipher */
|
||||||
|
unsigned long block_index; /* index # for current data block */
|
||||||
|
int cipher, /* cipher idx */
|
||||||
|
block_len; /* length of block */
|
||||||
|
} ocb3_state;
|
||||||
|
|
||||||
|
int ocb3_init(ocb3_state *ocb, int cipher,
|
||||||
|
const unsigned char *key, unsigned long keylen,
|
||||||
|
const unsigned char *nonce, unsigned long noncelen);
|
||||||
|
|
||||||
|
int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
|
||||||
|
int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
|
||||||
|
int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
|
||||||
|
int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
|
||||||
|
int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen);
|
||||||
|
int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen);
|
||||||
|
|
||||||
|
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 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 ocb3_test(void);
|
||||||
|
|
||||||
|
/* internal helper functions */
|
||||||
|
int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block);
|
||||||
|
void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen);
|
||||||
|
int ocb3_int_ntz(unsigned long x);
|
||||||
|
void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
|
||||||
|
|
||||||
|
#endif /* LTC_OCB3_MODE */
|
||||||
|
|
||||||
#ifdef LTC_CCM_MODE
|
#ifdef LTC_CCM_MODE
|
||||||
|
|
||||||
#define CCM_ENCRYPT 0
|
#define CCM_ENCRYPT 0
|
||||||
|
@ -231,6 +231,9 @@ const char *crypt_build_settings =
|
|||||||
#if defined(LTC_OCB_MODE)
|
#if defined(LTC_OCB_MODE)
|
||||||
" LTC_OCB_MODE\n"
|
" LTC_OCB_MODE\n"
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(LTC_OCB3_MODE)
|
||||||
|
" LTC_OCB3_MODE\n"
|
||||||
|
#endif
|
||||||
#if defined(LTC_CCM_MODE)
|
#if defined(LTC_CCM_MODE)
|
||||||
" LTC_CCM_MODE\n"
|
" LTC_CCM_MODE\n"
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,6 +24,9 @@ int mac_test(void)
|
|||||||
#ifdef LTC_OCB_MODE
|
#ifdef LTC_OCB_MODE
|
||||||
DO(ocb_test());
|
DO(ocb_test());
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef LTC_OCB3_MODE
|
||||||
|
DO(ocb3_test());
|
||||||
|
#endif
|
||||||
#ifdef LTC_CCM_MODE
|
#ifdef LTC_CCM_MODE
|
||||||
DO(ccm_test());
|
DO(ccm_test());
|
||||||
#endif
|
#endif
|
||||||
|
@ -1339,6 +1339,22 @@ void time_encmacs_(unsigned long MAC_SIZE)
|
|||||||
fprintf(stderr, "OCB \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
|
fprintf(stderr, "OCB \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LTC_OCB3_MODE
|
||||||
|
t2 = -1;
|
||||||
|
for (x = 0; x < 10000; x++) {
|
||||||
|
t_start();
|
||||||
|
t1 = t_read();
|
||||||
|
z = 16;
|
||||||
|
if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, "", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
|
||||||
|
fprintf(stderr, "\nOCB3 error... %s\n", error_to_string(err));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
t1 = t_read() - t1;
|
||||||
|
if (t1 < t2) t2 = t1;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "OCB3 \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LTC_CCM_MODE
|
#ifdef LTC_CCM_MODE
|
||||||
t2 = -1;
|
t2 = -1;
|
||||||
for (x = 0; x < 10000; x++) {
|
for (x = 0; x < 10000; x++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user