a little tweak
This commit is contained in:
26
README.md
26
README.md
@@ -2,13 +2,9 @@
|
||||
|
||||
**A minimalist ANSI-C compatible code for most of the AES-related algorithms**.
|
||||
|
||||
[](https://github.com/polfosol/micro-AES)  [](https://github.com/polfosol/micro-AES/files/9945712/micro_aes-v1.0.zip) [](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://github.com/polfosol/micro-AES)  [](https://github.com/polfosol/micro-AES/files/9952994/micro_aes-v1.0.1.zip) [](https://opensource.org/licenses/Apache-2.0)
|
||||
|
||||
This library is a highly flexible, all-in-one implementation of different AES encryption schemes and block ciphers modes. Before you continue, please keep in mind that, most security experts strongly warn *against* implementing your own version of AES—or other ciphering algorithms; AND THEY ARE ABSOLUTELY RIGHT!
|
||||
|
||||
Everyone who is becoming familiar with cryptography, should first sign [Jeff Moser's](https://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html) so-called "Foot Shooting Prevention Agreement". I have put a copy of it at the bottom of this page.
|
||||
|
||||
With that in mind, I shall say that the main purpose of developing µAES was purely educational. I learned a lot during writing these codes and I hope that somebody, some day, would gain a bit of knowledge from it.
|
||||
This library is a highly flexible, all-in-one implementation of different AES encryption schemes and block ciphers modes.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -40,14 +36,24 @@ With that in mind, I shall say that the main purpose of developing µAES was pur
|
||||
|
||||
## Remarks
|
||||
|
||||
For the sake of simplicity, it is often assumed that the input parameters of the functions are well defined, and the user knows what they're doing. As a result, a bunch of error checks are just skipped. Obviously, this is a naive and sometimes dangerous assumption. One must be aware that in a serious application, anything can be fed into the functions and they must take all the necessary precautions for erroneous parameters.
|
||||
* First and foremost, please keep in mind that most security experts strongly warn *against* implementing your own version of AES—or other ciphering algorithms; AND THEY ARE ABSOLUTELY RIGHT!
|
||||
|
||||
Part of µAES is palpably influenced by [kokke's tiny-AES](https://github.com/kokke/tiny-AES-c) library, but I have made some modifications to make it smaller and more efficient. I shall give kudos to their great effort which paved the way for many other branches.
|
||||
Everyone who is becoming familiar with cryptography, should first sign [Jeff Moser's](https://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html) so-called "Foot Shooting Prevention Agreement". To save you some clicks, I have put a copy of it below.
|
||||
|
||||
With that in mind, I shall say that the main purpose of developing µAES was purely educational. I learned a lot during writing these codes and I hope that somebody, some day, would gain a bit of knowledge from it.
|
||||
|
||||
* For the sake of simplicity, it is often assumed that the input parameters of the functions are well defined, and the user knows what they're doing. As a result, a bunch of error checks are just skipped. Obviously, this is a naive and sometimes dangerous assumption. One must be aware that in a serious application, anything can be fed into the functions and they must take all the necessary precautions for erroneous parameters.
|
||||
|
||||
* Part of µAES is palpably influenced by [kokke's tiny-AES](https://github.com/kokke/tiny-AES-c) library, but I have made some modifications to make it smaller and more efficient. I shall give kudos to their great effort which paved the way for many other branches.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://i.stack.imgur.com/SoY7x.png" alt="The foot-shooting prevention agreement taken from Jeff Moser's blog"/>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
All the contents of this repository (except the ones that I didn't write!) are subject to the terms of Apache 2.0 license.
|
||||
|
||||
Copyright © 2022 - polfosol
|
||||
|
||||
$In$ $sorrowful$ $memory$ $of$ [**_Mahsa Amini_**](https://en.wikipedia.org/wiki/Death_of_Mahsa_Amini) :black_heart:
|
||||
|
||||

|
||||
|
||||
2
main.c
2
main.c
@@ -124,7 +124,7 @@ int main()
|
||||
AES_Cipher(mainKey, 'D', a + 16, output + 48);
|
||||
check("encryption & decryption", output, test, 64);
|
||||
#endif
|
||||
#if ECB && AES_KEY_LENGTH != 32
|
||||
#if ECB && AES_KEY_LENGTH + 8 * !AES_PADDING == 24
|
||||
str2bytes(ecbcipher, test);
|
||||
AES_ECB_encrypt(key, input, st, output);
|
||||
check("ECB encryption", output, test, sizeof input);
|
||||
|
||||
713
micro_aes.c
713
micro_aes.c
@@ -2,7 +2,7 @@
|
||||
==============================================================================
|
||||
Name : micro_aes.c
|
||||
Author : polfosol
|
||||
Version : 9.5.0.0
|
||||
Version : 9.5.1.0
|
||||
Copyright : copyright © 2022 - polfosol
|
||||
Description : ANSI-C compatible implementation of µAES ™ library.
|
||||
==============================================================================
|
||||
@@ -154,24 +154,22 @@ static void xorBlock( const block_t src, block_t dest )
|
||||
Main functions for the Rijndael encryption algorithm
|
||||
\*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* This function produces (ROUNDS+1) round keys from the main encryption key,
|
||||
* which are used in each round to encrypt/decrypt the intermediate states.
|
||||
*/
|
||||
/** This function produces (ROUNDS+1) round keys, which are used in each round
|
||||
* to encrypt/decrypt the intermediate states. First round key is the main key
|
||||
* itself, and other rounds are constructed from the previous ones as follows */
|
||||
static void KeyExpansion( const uint8_t* key )
|
||||
{
|
||||
uint8_t rcon = 1, i;
|
||||
memcpy( RoundKey, key, KEYSIZE ); /* First round key is the key itself */
|
||||
memcpy( RoundKey, key, KEYSIZE );
|
||||
|
||||
for (i = KEYSIZE; i < (ROUNDS + 1) * BLOCKSIZE; ++i)
|
||||
{
|
||||
switch (i % KEYSIZE) /* Constructing other round keys */
|
||||
{ /* ..based on the previous ones: */
|
||||
switch (i % KEYSIZE)
|
||||
{
|
||||
case 0:
|
||||
memcpy( RoundKey + i, RoundKey + i - KEYSIZE, KEYSIZE );
|
||||
|
||||
#if Nk == 4 /* RCON may reach 0 only in AES-128. */
|
||||
if (rcon == 0) rcon = 0x1b;
|
||||
memcpy( &RoundKey[i], &RoundKey[i - KEYSIZE], KEYSIZE );
|
||||
#if Nk == 4
|
||||
if (rcon == 0) rcon = 0x1b; /* RCON may reach 0 only in AES-128. */
|
||||
#endif
|
||||
RoundKey[i] ^= getSBoxValue( RoundKey[i - 3] ) ^ rcon;
|
||||
rcon <<= 1;
|
||||
@@ -486,13 +484,12 @@ static void xorThenMix( const uint8_t* x, const uint8_t len,
|
||||
|
||||
#if CTS || defined(PARTIAL_DATA_PASS)
|
||||
|
||||
/** Result of applying a function to block `b` is xor-ed with `x` up to length
|
||||
* `len` to get `y`. A temporary block, `tmp` holds the intermediate values.. */
|
||||
/** Result of applying a function to block `b` is xor-ed with `x` to get `y`. */
|
||||
static void mixThenXor( const block_t b, fmix_t mix, block_t tmp,
|
||||
const uint8_t* x, const uint8_t len, uint8_t* y )
|
||||
{
|
||||
uint8_t i;
|
||||
if (len == 0) return;
|
||||
if (len == 0) return; /* f(B) = temp; Y = temp ^ X */
|
||||
|
||||
mix( b, tmp );
|
||||
for (i = 0; i < len; ++i) y[i] = tmp[i] ^ x[i];
|
||||
@@ -504,13 +501,13 @@ static void mixThenXor( const block_t b, fmix_t mix, block_t tmp,
|
||||
/** Multiply a block by two in Galois bit field GF(2^128): big-endian version */
|
||||
static void doubleGF128B( block_t block )
|
||||
{
|
||||
int i, t = 0;
|
||||
for (i = BLOCKSIZE; i--; t >>= 8) /* loop from last to first, */
|
||||
int i, d = 0;
|
||||
for (i = BLOCKSIZE; i--; d >>= 8) /* loop from last to first, */
|
||||
{ /* left-shift each byte and */
|
||||
t |= block[i] << 1; /* ..add the previous MSB. */
|
||||
block[i] = (uint8_t) t;
|
||||
d |= block[i] << 1; /* ..add the previous MSB. */
|
||||
block[i] = (uint8_t) d;
|
||||
} /* if first MSB is carried: */
|
||||
if (t) block[BLOCKSIZE - 1] ^= 0x87; /* B ^= 10000111b (B.E.) */
|
||||
if (d) block[BLOCKSIZE - 1] ^= 0x87; /* B ^= 10000111b (B.E.) */
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -519,13 +516,13 @@ static void doubleGF128B( block_t block )
|
||||
/** Multiply a block by two in GF(2^128) field: this is little-endian version */
|
||||
static void doubleGF128L( block_t block )
|
||||
{
|
||||
int t = 0, i;
|
||||
for (i = 0; i < BLOCKSIZE; t >>= 8) /* the same as doubleGF128B */
|
||||
int d = 0, i;
|
||||
for (i = 0; i < BLOCKSIZE; d >>= 8) /* the same as doubleGF128B */
|
||||
{ /* ..but with reversed bytes */
|
||||
t |= block[i] << 1;
|
||||
block[i++] = (uint8_t) t;
|
||||
d |= block[i] << 1;
|
||||
block[i++] = (uint8_t) d;
|
||||
}
|
||||
if (t) block[0] ^= 0x87; /* B ^= 10000111b (L.E.) */
|
||||
if (d) block[0] ^= 0x87; /* B ^= 10000111b (L.E.) */
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -597,53 +594,26 @@ static void dotGF128( const block_t x, block_t y )
|
||||
}
|
||||
#endif /* GCM-SIV */
|
||||
|
||||
#if OCB
|
||||
|
||||
static void nop( const block_t x, block_t y ) {}
|
||||
|
||||
/** get the offset block (Δ_i) at a specified index for a given L$ and Δ_0 .. */
|
||||
static void getOffset( const block_t Ld, const count_t index, block_t delta )
|
||||
{
|
||||
size_t b, m; /* this method uses minimum */
|
||||
block_t L; /* ..memory, but it's slow */
|
||||
memcpy( L, Ld, sizeof L ); /* initialize L_$ */
|
||||
|
||||
for (b = 1; b <= index && b; ) /* we can pre-calculate all */
|
||||
{ /* ..L_{i}s to boost speed */
|
||||
m = (4 * b - 1) & (index - b);
|
||||
b <<= 1; /* L_0 = double( L_$ ) */
|
||||
doubleGF128B( L ); /* L_i = double( L_{i-1} ) */
|
||||
if (b > m) xorBlock( L, delta ); /* Δ_new = Δ ^ L_i */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if POLY1305
|
||||
|
||||
/** compare a little-endian block with Poly1305; return sign of B - (2^130-5) */
|
||||
static int cmpWith1305( uint8_t* block )
|
||||
{
|
||||
int i = BLOCKSIZE, c = 0xFC;
|
||||
do
|
||||
c -= 0xFF - block[i];
|
||||
while (c == 0 && --i); /* loop from MSB to LSB */
|
||||
|
||||
return i ? c : block[0] - 0xFB;
|
||||
}
|
||||
|
||||
/** derive modulo(2^130-5) for a little endian block, by repeated subtraction */
|
||||
static void modLBlock( uint8_t* block, uint8_t ovf )
|
||||
static void modLPoly( uint8_t* block, uint8_t carry )
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 1; ovf || cmpWith1305( block ) >= 0; i = 1)
|
||||
{
|
||||
if ((uint8_t) (block[0] += 5) < 5) /* while B >= (2^130-5) */
|
||||
{ /* ..subtract it from B */
|
||||
while (!++block[i] && ++i < Np); /* to get B - (2^130-5), we */
|
||||
} /* ..first calculate (B + 5) */
|
||||
ovf -= (block[BLOCKSIZE] < 4 && ovf); /* ..then subtract 2 ^ 130 */
|
||||
block[BLOCKSIZE] += 0xFC; /* (since x - 4 ≡ x + 0xFC) */
|
||||
int i = Np - 1, n = block[Np - 1] / 4 + carry * 0x40;
|
||||
long q = n - (block[i] < 3);
|
||||
while (q == 0 && --i) /* n = B / (2 ^ 130) */
|
||||
{ /* compare block to 2^130-5 */
|
||||
q -= 0xFF - block[i]; /* return if B < (2^130-5) */
|
||||
}
|
||||
if (q < 0 || (i == 0 && ++n && *block < 0xFB)) return;
|
||||
|
||||
q = 5 * n;
|
||||
for (i = 0; q && i < Np; q >>= 8) /* mod = B - n * (2^130-5) */
|
||||
{ /* to get mod, first derive */
|
||||
q += block[i]; /* .. B + (5 * n) and then */
|
||||
block[i++] = (uint8_t) q; /* .. subtract n * (2^130) */
|
||||
}
|
||||
block[BLOCKSIZE] -= 4 * (uint8_t) n;
|
||||
}
|
||||
|
||||
/** add two little-endian poly1305 blocks. use modular addition if necessary. */
|
||||
@@ -655,7 +625,7 @@ static void addLBlocks( const uint8_t* x, const uint8_t len, uint8_t* y )
|
||||
s += x[i] + y[i];
|
||||
y[i++] = (uint8_t) s; /* s >> 8 is the overflow */
|
||||
}
|
||||
if (len == Np) modLBlock( y, (uint8_t) s );
|
||||
if (len == Np) modLPoly( y, (uint8_t) s );
|
||||
}
|
||||
|
||||
/** modular multiplication of a block by 2^s, i.e. left shift block to s bits */
|
||||
@@ -667,7 +637,7 @@ static void shiftLBlock( uint8_t* block, const uint8_t shl )
|
||||
t |= block[i] << shl; /* shl may vary from 1 to 8 */
|
||||
block[i++] = (uint8_t) t;
|
||||
}
|
||||
modLBlock( block, (uint8_t) t );
|
||||
modLPoly( block, (uint8_t) t );
|
||||
}
|
||||
|
||||
/** modular multiplication of two little-endian poly1305 blocks. y *= x mod P */
|
||||
@@ -1533,297 +1503,6 @@ char AES_SIV_decrypt( const uint8_t* keys, const block_t iv,
|
||||
#endif /* SIV */
|
||||
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
EAX-AES (encrypt-then-authenticate-then-translate): OMAC & main functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
#if IMPLEMENT(EAX)
|
||||
|
||||
/** this function calculates the OMAC hash of a data array using D (K1) and Q */
|
||||
static void OMac( const uint8_t t, const block_t D, const block_t Q,
|
||||
const void* data, const size_t dataSize, block_t mac )
|
||||
{
|
||||
block_t M = { 0 };
|
||||
#if EAXP
|
||||
memcpy( mac, t ? (dataSize ? Q : M) : D, sizeof M );
|
||||
if (dataSize || !t) /* ignore null ciphertext */
|
||||
#else
|
||||
if (dataSize == 0)
|
||||
{
|
||||
memcpy( M, D, sizeof M ); /* OMAC = Enc( D ^ [t]_n ) */
|
||||
}
|
||||
M[sizeof M - 1] ^= t; /* else: C1 = Enc( [t]_n ) */
|
||||
rijndaelEncrypt( M, mac );
|
||||
#endif
|
||||
cMac( D, Q, data, dataSize, mac );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief encrypt the input plaintext using EAX-AES block-cipher method
|
||||
* @param key encryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with EAX_NONCE_LEN bytes if not EAX'
|
||||
* @param pText input plain-text buffer
|
||||
* @param pTextLen size of plaintext in bytes
|
||||
* @param nonceLen size of the nonce byte array; should be non-zero in EAX'
|
||||
* @param aData additional authentication data
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param cText resulting cipher-text buffer; 4 bytes mac appended in EAX'
|
||||
* @param auTag authentication tag; buffer must be 16 bytes long in EAX
|
||||
*/
|
||||
void AES_EAX_encrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* pText, const size_t pTextLen,
|
||||
#if EAXP
|
||||
const size_t nonceLen, uint8_t* cText )
|
||||
#define blockMul2 doubleGF128L
|
||||
#else
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
uint8_t* cText, uint8_t* auTag )
|
||||
#define blockMul2 doubleGF128B
|
||||
#endif
|
||||
{
|
||||
block_t mac, tag, D = { 0 }, K2;
|
||||
getSubkeys( key, &blockMul2, D, K2 );
|
||||
|
||||
#if EAXP
|
||||
OMac( 0, D, K2, nonce, nonceLen, mac ); /* N = CMAC'( nonce ) */
|
||||
memcpy( cText + pTextLen, mac + 12, 4 );
|
||||
mac[12] &= 0x7F; /* clear 2 bits to get N' */
|
||||
mac[14] &= 0x7F;
|
||||
CTR_Cipher( mac, 1, pText, pTextLen, cText );
|
||||
|
||||
OMac( 2, D, K2, cText, pTextLen, tag ); /* C' = CMAC'( ciphertext ) */
|
||||
for (*D = 0; *D < 4; ++*D) /* using D[0] as counter! */
|
||||
{
|
||||
cText[pTextLen + *D] ^= tag[12 + *D]; /* last 4 bytes of C' ^ N' */
|
||||
}
|
||||
#else
|
||||
OMac( 0, D, K2, nonce, EAX_NONCE_LEN, mac ); /* N = OMAC(0; nonce) */
|
||||
OMac( 1, D, K2, aData, aDataLen, tag ); /* H = OMAC(1; adata) */
|
||||
xorBlock( mac, tag );
|
||||
memcpy( auTag, tag, sizeof tag );
|
||||
CTR_Cipher( mac, 1, pText, pTextLen, cText );
|
||||
|
||||
OMac( 2, D, K2, cText, pTextLen, mac ); /* C = OMAC(2; ciphertext) */
|
||||
xorBlock( mac, auTag ); /* tag = N ^ H ^ C */
|
||||
#endif
|
||||
BURN( RoundKey );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief decrypt the input ciphertext using EAX-AES block-cipher method
|
||||
* @param key decryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with EAX_NONCE_LEN bytes if not EAX'
|
||||
* @param cText input cipher-text buffer + appended authentication tag
|
||||
* @param cTextLen size of cipher-text; excluding tag / 4-bytes mac in EAX'
|
||||
* @param nonceLen size of the nonce byte array; should be non-zero in EAX'
|
||||
* @param aData additional authentication data; ignored in EAX'
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param tagLen length of authentication tag; mandatory 4 bytes in EAX'
|
||||
* @param pText resulting plaintext buffer
|
||||
* @return whether message authentication was successful
|
||||
*/
|
||||
char AES_EAX_decrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* cText, const size_t cTextLen,
|
||||
#if EAXP
|
||||
const size_t nonceLen,
|
||||
#else
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
const uint8_t tagLen,
|
||||
#endif
|
||||
uint8_t* pText )
|
||||
{
|
||||
block_t mac, tag, D = { 0 }, K2;
|
||||
getSubkeys( key, &blockMul2, D, K2 );
|
||||
OMac( 2, D, K2, cText, cTextLen, tag ); /* C = OMAC(2; ciphertext) */
|
||||
|
||||
#if EAXP
|
||||
OMac( 0, D, K2, nonce, nonceLen, mac ); /* N = CMAC'( nonce ) */
|
||||
for (*K2 = *D = 0; *D < 4; ++*D) /* authenticate/compare tags */
|
||||
{
|
||||
*K2 |= cText[cTextLen + *D] ^ tag[12 + *D] ^ mac[12 + *D];
|
||||
}
|
||||
mac[12] &= 0x7F; /* clear 2 bits to get N' */
|
||||
mac[14] &= 0x7F;
|
||||
if (*K2 != 0) /* result of tag comparison */
|
||||
#else
|
||||
OMac( 1, D, K2, aData, aDataLen, mac ); /* H = OMAC(1; adata) */
|
||||
xorBlock( mac, tag ); /* N = OMAC(0; nonce) */
|
||||
OMac( 0, D, K2, nonce, EAX_NONCE_LEN, mac );
|
||||
xorBlock( mac, tag ); /* tag = N ^ H ^ C */
|
||||
|
||||
if (MISMATCH( tag, cText + cTextLen, tagLen ))
|
||||
#endif
|
||||
{ /* authenticate then decrypt */
|
||||
BURN( RoundKey );
|
||||
return AUTHENTICATION_FAILURE;
|
||||
}
|
||||
CTR_Cipher( mac, 1, cText, cTextLen, pText );
|
||||
|
||||
BURN( RoundKey );
|
||||
return ENDED_IN_SUCCESS;
|
||||
}
|
||||
#endif /* EAX */
|
||||
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
OCB-AES (offset codebook mode): auxiliary functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
#if IMPLEMENT(OCB)
|
||||
/**
|
||||
* @brief encrypt or decrypt a data unit using OCB-AES method
|
||||
* @param nonce a.k.a init-vector with a fixed size of 12 bytes
|
||||
* @param cipher block-cipher function: rijndaelEncrypt or rijndaelDecrypt
|
||||
* @param input input plain/cipher-text buffer
|
||||
* @param dataSize size of data
|
||||
* @param Ls L_* is the result of the encryption of a zero block
|
||||
* @param Ld L_$ = double(L_*) in GF(2^128)
|
||||
* @param Del Δ_m a.k.a last offset (sometimes Δ*, which is Δ_m ^ L_*)
|
||||
* @param output encrypted/decrypted data storage
|
||||
*/
|
||||
static void OCB_Cipher( const uint8_t* nonce, fmix_t cipher,
|
||||
const void* input, const size_t dataSize,
|
||||
block_t Ls, block_t Ld, block_t Del, void* output )
|
||||
{
|
||||
uint8_t Kt[2 * BLOCKSIZE] = { OCB_TAG_LEN << 4 & 0xFF, 0, 0, 1 };
|
||||
uint8_t r, *y = output;
|
||||
count_t i, n;
|
||||
memcpy( output, input, dataSize ); /* copy input data to output */
|
||||
|
||||
n = nonce[11] % 64 >> 3;
|
||||
r = nonce[11] % 8; /* take last 6 bits of nonce */
|
||||
memcpy( Kt + 4, nonce, 12 );
|
||||
Kt[BLOCKSIZE - 1] &= 0xC0; /* clear last 6 bits */
|
||||
|
||||
rijndaelEncrypt( Kt, Kt ); /* construct K_top */
|
||||
memcpy( Kt + BLOCKSIZE, Kt + 1, 8 ); /* stretch K_top */
|
||||
xorBlock( Kt, Kt + BLOCKSIZE );
|
||||
for (i = 0; i < BLOCKSIZE; ++n) /* shift the stretched K_top */
|
||||
{
|
||||
Kt[i++] = Kt[n] << r | Kt[n + 1] >> (8 - r);
|
||||
}
|
||||
n = dataSize / BLOCKSIZE;
|
||||
r = dataSize % BLOCKSIZE;
|
||||
|
||||
rijndaelEncrypt( Ls, Ls ); /* L_* = Enc(zero block) */
|
||||
memcpy( Ld, Ls, BLOCKSIZE );
|
||||
doubleGF128B( Ld ); /* L_$ = double(L_*) */
|
||||
if (n == 0) /* processed nonce is Δ_0 */
|
||||
{
|
||||
memcpy( Del, Kt, BLOCKSIZE ); /* initialize Δ_0 */
|
||||
}
|
||||
for (i = 0; i < n; y += BLOCKSIZE)
|
||||
{
|
||||
memcpy( Del, Kt, BLOCKSIZE ); /* calculate Δ_i using my */
|
||||
getOffset( Ld, ++i, Del ); /* .. 'magic' algorithm */
|
||||
xorBlock( Del, y );
|
||||
cipher( y, y ); /* Y = Δ_i ^ Cipher(Δ_i ^ X) */
|
||||
xorBlock( Del, y );
|
||||
}
|
||||
if (r) /* Δ_* = Δ_n ^ L_* and then */
|
||||
{ /* Y_* = Enc(Δ_*) ^ X */
|
||||
xorBlock( Ls, Del );
|
||||
mixThenXor( Del, &rijndaelEncrypt, Kt, y, r, y );
|
||||
Del[r] ^= 0x80; /* pad it for checksum */
|
||||
}
|
||||
}
|
||||
|
||||
/** this function calculates the authentication tag in OCB-AES method. the first
|
||||
* three arguments must be pre-calculated. Ls denotes L_* which is encryption of
|
||||
* zero block. Ld denotes L_$ = double(L_*), and Ds is Δ_* (or sometimes Δ_m) */
|
||||
static void OCB_GetTag( const block_t Ds,
|
||||
const block_t Ls, const block_t Ld,
|
||||
const void* pText, const void* aData,
|
||||
const size_t pTextLen, const size_t aDataLen,
|
||||
block_t tag )
|
||||
{
|
||||
uint8_t const r = aDataLen % BLOCKSIZE, *x = aData;
|
||||
count_t i, n = aDataLen / BLOCKSIZE;
|
||||
|
||||
block_t S = { 0 }; /* checksum, i.e. */
|
||||
MAC( pText, pTextLen, NULL, &nop, S ); /* ..xor of all plaintext */
|
||||
|
||||
xorBlock( Ds, S );
|
||||
xorBlock( Ld, S );
|
||||
rijndaelEncrypt( S, tag ); /* Tag0 = Enc(L_$ ^ Δ_* ^ S) */
|
||||
if (aDataLen == 0) return;
|
||||
|
||||
memset( S, 0, sizeof S ); /* PMAC authentication: */
|
||||
for (i = 0; i < n; x += BLOCKSIZE)
|
||||
{
|
||||
getOffset( Ld, ++i, S );
|
||||
xorBlock( x, S );
|
||||
rijndaelEncrypt( S, S ); /* S_i = Enc(A_i ^ Δ_i) */
|
||||
xorBlock( S, tag ); /* Tag_{i+1} = Tag_i ^ S_i */
|
||||
memset( S, 0, sizeof S );
|
||||
}
|
||||
if (r)
|
||||
{
|
||||
getOffset( Ld, n, S ); /* S = calculated Δ_n */
|
||||
S[r] ^= 0x80; /* A_* = A || 1 (padded) */
|
||||
xorThenMix( x, r, Ls, &xorBlock, S ); /* S_* = A_* ^ L_* ^ Δ_n */
|
||||
rijndaelEncrypt( S, S );
|
||||
xorBlock( S, tag ); /* Tag = Enc(S_*) ^ Tag_n */
|
||||
}
|
||||
}
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
OCB-AES (offset codebook mode): main functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief encrypt the input stream using OCB-AES block-cipher method
|
||||
* @param key encryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with a fixed size of 12 bytes
|
||||
* @param pText input plain-text buffer
|
||||
* @param pTextLen size of plaintext in bytes
|
||||
* @param aData additional authentication data
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param cText resulting cipher-text buffer
|
||||
* @param auTag message authentication tag. buffer must be 16-bytes long
|
||||
*/
|
||||
void AES_OCB_encrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* pText, const size_t pTextLen,
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
uint8_t* cText, block_t auTag )
|
||||
{
|
||||
block_t Ls = { 0 }, Ld, delta;
|
||||
AES_SetKey( key );
|
||||
OCB_Cipher( nonce, &rijndaelEncrypt, pText, pTextLen, Ls, Ld, delta, cText );
|
||||
OCB_GetTag( delta, Ls, Ld, pText, aData, pTextLen, aDataLen, auTag );
|
||||
BURN( RoundKey );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief decrypt the input stream using OCB-AES block-cipher method
|
||||
* @param key decryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with a fixed size of 12 bytes
|
||||
* @param cText input cipher-text buffer + appended authentication tag
|
||||
* @param cTextLen size of ciphertext, excluding tag
|
||||
* @param aData additional authentication data
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param tagLen length of authentication tag
|
||||
* @param pText resulting plaintext buffer
|
||||
* @return whether message authentication was successful
|
||||
*/
|
||||
char AES_OCB_decrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* cText, const size_t cTextLen,
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
const uint8_t tagLen, uint8_t* pText )
|
||||
{
|
||||
block_t Ls = { 0 }, Ld, delta;
|
||||
AES_SetKey( key );
|
||||
OCB_Cipher( nonce, &rijndaelDecrypt, cText, cTextLen, Ls, Ld, delta, pText );
|
||||
OCB_GetTag( delta, Ls, Ld, pText, aData, cTextLen, aDataLen, delta );
|
||||
BURN( RoundKey ); /* saved the tag into delta! */
|
||||
|
||||
if (MISMATCH( delta, cText + cTextLen, tagLen ))
|
||||
{
|
||||
SABOTAGE( pText, cTextLen );
|
||||
return AUTHENTICATION_FAILURE;
|
||||
}
|
||||
return ENDED_IN_SUCCESS;
|
||||
}
|
||||
#endif /* OCB */
|
||||
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
SIV-GCM-AES (Galois counter mode with synthetic i.v): main functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
@@ -1937,6 +1616,316 @@ char GCM_SIV_decrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
#endif /* GCM-SIV */
|
||||
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
EAX-AES (encrypt-then-authenticate-then-translate): OMAC & main functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
#if IMPLEMENT(EAX)
|
||||
|
||||
/** this function calculates the OMAC hash of a data array using D (K1) and Q */
|
||||
static void OMac( const uint8_t t, const block_t D, const block_t Q,
|
||||
const void* data, const size_t dataSize, block_t mac )
|
||||
{
|
||||
block_t M = { 0 };
|
||||
#if EAXP
|
||||
memcpy( mac, t ? (dataSize ? Q : M) : D, sizeof M );
|
||||
if (dataSize || !t) /* ignore null ciphertext */
|
||||
#else
|
||||
if (dataSize == 0)
|
||||
{
|
||||
memcpy( M, D, sizeof M ); /* OMAC = Enc( D ^ [t]_n ) */
|
||||
}
|
||||
M[sizeof M - 1] ^= t; /* else: C1 = Enc( [t]_n ) */
|
||||
rijndaelEncrypt( M, mac );
|
||||
#endif
|
||||
cMac( D, Q, data, dataSize, mac );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief encrypt the input plaintext using EAX-AES block-cipher method
|
||||
* @param key encryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with EAX_NONCE_LEN bytes if not EAX'
|
||||
* @param pText input plain-text buffer
|
||||
* @param pTextLen size of plaintext in bytes
|
||||
* @param nonceLen size of the nonce byte array; should be non-zero in EAX'
|
||||
* @param aData additional authentication data
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param cText resulting cipher-text buffer; 4 bytes mac appended in EAX'
|
||||
* @param auTag authentication tag; buffer must be 16 bytes long in EAX
|
||||
*/
|
||||
void AES_EAX_encrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* pText, const size_t pTextLen,
|
||||
#if EAXP
|
||||
const size_t nonceLen, uint8_t* cText )
|
||||
#define gfDouble doubleGF128L
|
||||
#else
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
uint8_t* cText, uint8_t* auTag )
|
||||
#define gfDouble doubleGF128B
|
||||
#define nonceLen EAX_NONCE_LEN
|
||||
#endif
|
||||
{
|
||||
block_t D = { 0 }, K2, mac, tag;
|
||||
getSubkeys( key, &gfDouble, D, K2 );
|
||||
OMac( 0, D, K2, nonce, nonceLen, mac ); /* N = OMAC(0; nonce) */
|
||||
|
||||
#if EAXP
|
||||
memcpy( cText + pTextLen, mac + 12, 4 );
|
||||
mac[12] &= 0x7F; /* clear 2 bits to get N' */
|
||||
mac[14] &= 0x7F;
|
||||
CTR_Cipher( mac, 1, pText, pTextLen, cText );
|
||||
|
||||
OMac( 2, D, K2, cText, pTextLen, tag ); /* C' = CMAC'( ciphertext ) */
|
||||
for (*D = 0; *D < 4; ++*D) /* using D[0] as counter! */
|
||||
{
|
||||
cText[pTextLen + *D] ^= tag[12 + *D]; /* last 4 bytes of C' ^ N' */
|
||||
}
|
||||
#else
|
||||
OMac( 1, D, K2, aData, aDataLen, tag ); /* H = OMAC(1; adata) */
|
||||
xorBlock( mac, tag );
|
||||
memcpy( auTag, tag, sizeof tag );
|
||||
CTR_Cipher( mac, 1, pText, pTextLen, cText );
|
||||
|
||||
OMac( 2, D, K2, cText, pTextLen, mac ); /* C = OMAC(2; ciphertext) */
|
||||
xorBlock( mac, auTag ); /* tag = N ^ H ^ C */
|
||||
#endif
|
||||
BURN( RoundKey );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief decrypt the input ciphertext using EAX-AES block-cipher method
|
||||
* @param key decryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with EAX_NONCE_LEN bytes if not EAX'
|
||||
* @param cText input cipher-text buffer + appended authentication tag
|
||||
* @param cTextLen size of cipher-text; excluding tag / 4-bytes mac in EAX'
|
||||
* @param nonceLen size of the nonce byte array; should be non-zero in EAX'
|
||||
* @param aData additional authentication data; ignored in EAX'
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param tagLen length of authentication tag; mandatory 4 bytes in EAX'
|
||||
* @param pText resulting plaintext buffer
|
||||
* @return whether message authentication was successful
|
||||
*/
|
||||
char AES_EAX_decrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* cText, const size_t cTextLen,
|
||||
#if EAXP
|
||||
const size_t nonceLen,
|
||||
#else
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
const uint8_t tagLen,
|
||||
#endif
|
||||
uint8_t* pText )
|
||||
{
|
||||
block_t D = { 0 }, K2, mac, tag;
|
||||
getSubkeys( key, &gfDouble, D, K2 );
|
||||
OMac( 2, D, K2, cText, cTextLen, tag ); /* C = OMAC(2; ciphertext) */
|
||||
|
||||
#if EAXP
|
||||
OMac( 0, D, K2, nonce, nonceLen, mac ); /* N = CMAC'( nonce ) */
|
||||
for (*K2 = *D = 0; *D < 4; ++*D) /* authenticate/compare tags */
|
||||
{
|
||||
*K2 |= cText[cTextLen + *D] ^ tag[12 + *D] ^ mac[12 + *D];
|
||||
}
|
||||
mac[12] &= 0x7F; /* clear 2 bits to get N' */
|
||||
mac[14] &= 0x7F;
|
||||
if (*K2 != 0) /* result of tag comparison */
|
||||
#else
|
||||
OMac( 1, D, K2, aData, aDataLen, mac ); /* H = OMAC(1; adata) */
|
||||
xorBlock( mac, tag );
|
||||
OMac( 0, D, K2, nonce, nonceLen, mac ); /* N = OMAC(0; nonce) */
|
||||
xorBlock( mac, tag ); /* tag = N ^ H ^ C */
|
||||
|
||||
if (MISMATCH( tag, cText + cTextLen, tagLen ))
|
||||
#endif
|
||||
{ /* authenticate then decrypt */
|
||||
BURN( RoundKey );
|
||||
return AUTHENTICATION_FAILURE;
|
||||
}
|
||||
CTR_Cipher( mac, 1, cText, cTextLen, pText );
|
||||
|
||||
BURN( RoundKey );
|
||||
return ENDED_IN_SUCCESS;
|
||||
}
|
||||
#endif /* EAX */
|
||||
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
OCB-AES (offset codebook mode): auxiliary functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
#if IMPLEMENT(OCB)
|
||||
|
||||
/** Get the offset block (Δ_i) which is initialized by Δ_0, at the specified
|
||||
* index for a given L$. This method has minimum memory usage, but it is slow */
|
||||
static void OffsetB( const block_t Ld, const count_t index, block_t delta )
|
||||
{
|
||||
size_t b, m;
|
||||
block_t L;
|
||||
memcpy( L, Ld, sizeof L ); /* initialize L_$ */
|
||||
|
||||
for (b = 1; b <= index && b; ) /* we can pre-calculate all */
|
||||
{ /* ..L_{i}s to boost speed */
|
||||
m = (4 * b - 1) & (index - b);
|
||||
b <<= 1; /* L_0 = double( L_$ ) */
|
||||
doubleGF128B( L ); /* L_i = double( L_{i-1} ) */
|
||||
if (b > m) xorBlock( L, delta ); /* Δ_new = Δ ^ L_i */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief encrypt or decrypt a data unit using OCB-AES method
|
||||
* @param nonce a.k.a init-vector with a fixed size of 12 bytes
|
||||
* @param cipher block-cipher function: rijndaelEncrypt or rijndaelDecrypt
|
||||
* @param input input plain/cipher-text buffer
|
||||
* @param dataSize size of data
|
||||
* @param Ls L_* is the result of the encryption of a zero block
|
||||
* @param Ld L_$ = double(L_*) in GF(2^128)
|
||||
* @param Del Δ_m a.k.a last offset (sometimes Δ*, which is Δ_m ^ L_*)
|
||||
* @param output encrypted/decrypted data storage
|
||||
*/
|
||||
static void OCB_Cipher( const uint8_t* nonce, fmix_t cipher,
|
||||
const void* input, const size_t dataSize,
|
||||
block_t Ls, block_t Ld, block_t Del, void* output )
|
||||
{
|
||||
uint8_t Kt[2 * BLOCKSIZE] = { OCB_TAG_LEN << 4 & 0xFF, 0, 0, 1 };
|
||||
uint8_t r, *y = output;
|
||||
count_t i, n;
|
||||
memcpy( output, input, dataSize ); /* copy input data to output */
|
||||
|
||||
n = nonce[11] % 64 >> 3;
|
||||
r = nonce[11] % 8; /* take last 6 bits of nonce */
|
||||
memcpy( Kt + 4, nonce, 12 );
|
||||
Kt[BLOCKSIZE - 1] &= 0xC0; /* clear last 6 bits */
|
||||
|
||||
rijndaelEncrypt( Kt, Kt ); /* construct K_top */
|
||||
memcpy( Kt + BLOCKSIZE, Kt + 1, 8 ); /* stretch K_top */
|
||||
xorBlock( Kt, Kt + BLOCKSIZE );
|
||||
for (i = 0; i < BLOCKSIZE; ++n) /* shift the stretched K_top */
|
||||
{
|
||||
Kt[i++] = Kt[n] << r | Kt[n + 1] >> (8 - r);
|
||||
}
|
||||
n = dataSize / BLOCKSIZE;
|
||||
r = dataSize % BLOCKSIZE;
|
||||
|
||||
rijndaelEncrypt( Ls, Ls ); /* L_* = Enc(zero block) */
|
||||
memcpy( Ld, Ls, BLOCKSIZE );
|
||||
doubleGF128B( Ld ); /* L_$ = double(L_*) */
|
||||
if (n == 0) /* processed nonce is Δ_0 */
|
||||
{
|
||||
memcpy( Del, Kt, BLOCKSIZE ); /* initialize Δ_0 */
|
||||
}
|
||||
for (i = 0; i < n; y += BLOCKSIZE)
|
||||
{
|
||||
memcpy( Del, Kt, BLOCKSIZE ); /* calculate Δ_i using my */
|
||||
OffsetB( Ld, ++i, Del ); /* .. 'magic' algorithm */
|
||||
xorBlock( Del, y );
|
||||
cipher( y, y ); /* Y = Δ_i ^ Cipher(Δ_i ^ X) */
|
||||
xorBlock( Del, y );
|
||||
}
|
||||
if (r) /* Δ_* = Δ_n ^ L_* and then */
|
||||
{ /* Y_* = Enc(Δ_*) ^ X */
|
||||
xorBlock( Ls, Del );
|
||||
mixThenXor( Del, &rijndaelEncrypt, Kt, y, r, y );
|
||||
Del[r] ^= 0x80; /* pad it for checksum */
|
||||
}
|
||||
}
|
||||
|
||||
static void nop( const block_t x, block_t y ) {}
|
||||
|
||||
/** derives OCB authentication tag. the first three arguments are pre-calculated
|
||||
* namely, Δ_* (or sometimes Δ_m), L_* = encrypt(zeros) and L_$ = double(L_*) */
|
||||
static void OCB_GetTag( const block_t Ds,
|
||||
const block_t Ls, const block_t Ld,
|
||||
const void* pText, const void* aData,
|
||||
const size_t pTextLen, const size_t aDataLen,
|
||||
block_t tag )
|
||||
{
|
||||
uint8_t const r = aDataLen % BLOCKSIZE, *x = aData;
|
||||
count_t i, n = aDataLen / BLOCKSIZE;
|
||||
|
||||
block_t S = { 0 }; /* checksum, i.e. */
|
||||
MAC( pText, pTextLen, NULL, &nop, S ); /* ..xor of all plaintext */
|
||||
|
||||
xorBlock( Ds, S );
|
||||
xorBlock( Ld, S );
|
||||
rijndaelEncrypt( S, tag ); /* Tag0 = Enc(L_$ ^ Δ_* ^ S) */
|
||||
if (aDataLen == 0) return;
|
||||
|
||||
memset( S, 0, sizeof S ); /* PMAC authentication: */
|
||||
for (i = 0; i < n; x += BLOCKSIZE)
|
||||
{
|
||||
OffsetB( Ld, ++i, S );
|
||||
xorBlock( x, S );
|
||||
rijndaelEncrypt( S, S ); /* S_i = Enc(A_i ^ Δ_i) */
|
||||
xorBlock( S, tag ); /* Tag_{i+1} = Tag_i ^ S_i */
|
||||
memset( S, 0, sizeof S );
|
||||
}
|
||||
if (r)
|
||||
{
|
||||
OffsetB( Ld, n, S ); /* S = calculated Δ_n */
|
||||
S[r] ^= 0x80; /* A_* = A || 1 (padded) */
|
||||
xorThenMix( x, r, Ls, &xorBlock, S ); /* S_* = A_* ^ L_* ^ Δ_n */
|
||||
rijndaelEncrypt( S, S );
|
||||
xorBlock( S, tag ); /* Tag = Enc(S_*) ^ Tag_n */
|
||||
}
|
||||
}
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
OCB-AES (offset codebook mode): main functions
|
||||
\*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief encrypt the input stream using OCB-AES block-cipher method
|
||||
* @param key encryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with a fixed size of 12 bytes
|
||||
* @param pText input plain-text buffer
|
||||
* @param pTextLen size of plaintext in bytes
|
||||
* @param aData additional authentication data
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param cText resulting cipher-text buffer
|
||||
* @param auTag message authentication tag. buffer must be 16-bytes long
|
||||
*/
|
||||
void AES_OCB_encrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* pText, const size_t pTextLen,
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
uint8_t* cText, block_t auTag )
|
||||
{
|
||||
block_t Ls = { 0 }, Ld, delta;
|
||||
AES_SetKey( key );
|
||||
OCB_Cipher( nonce, &rijndaelEncrypt, pText, pTextLen, Ls, Ld, delta, cText );
|
||||
OCB_GetTag( delta, Ls, Ld, pText, aData, pTextLen, aDataLen, auTag );
|
||||
BURN( RoundKey );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief decrypt the input stream using OCB-AES block-cipher method
|
||||
* @param key decryption key with a fixed size specified by KEYSIZE
|
||||
* @param nonce a.k.a init-vector with a fixed size of 12 bytes
|
||||
* @param cText input cipher-text buffer + appended authentication tag
|
||||
* @param cTextLen size of ciphertext, excluding tag
|
||||
* @param aData additional authentication data
|
||||
* @param aDataLen size of additional authentication data
|
||||
* @param tagLen length of authentication tag
|
||||
* @param pText resulting plaintext buffer
|
||||
* @return whether message authentication was successful
|
||||
*/
|
||||
char AES_OCB_decrypt( const uint8_t* key, const uint8_t* nonce,
|
||||
const uint8_t* cText, const size_t cTextLen,
|
||||
const uint8_t* aData, const size_t aDataLen,
|
||||
const uint8_t tagLen, uint8_t* pText )
|
||||
{
|
||||
block_t Ls = { 0 }, Ld, delta;
|
||||
AES_SetKey( key );
|
||||
OCB_Cipher( nonce, &rijndaelDecrypt, cText, cTextLen, Ls, Ld, delta, pText );
|
||||
OCB_GetTag( delta, Ls, Ld, pText, aData, cTextLen, aDataLen, delta );
|
||||
BURN( RoundKey ); /* tag was saved into delta */
|
||||
|
||||
if (MISMATCH( delta, cText + cTextLen, tagLen ))
|
||||
{
|
||||
SABOTAGE( pText, cTextLen );
|
||||
return AUTHENTICATION_FAILURE;
|
||||
}
|
||||
return ENDED_IN_SUCCESS;
|
||||
}
|
||||
#endif /* OCB */
|
||||
|
||||
|
||||
/**--------------------------------------------------------------------------**\
|
||||
KW-AES: Main functions for AES key-wrapping (RFC-3394)
|
||||
\*----------------------------------------------------------------------------*/
|
||||
@@ -2010,7 +1999,6 @@ char AES_KEY_unwrap( const uint8_t* kek,
|
||||
BURN( RoundKey );
|
||||
return j ? DECRYPTION_FAILURE : ENDED_IN_SUCCESS;
|
||||
}
|
||||
#undef Nh
|
||||
#endif /* KWA */
|
||||
|
||||
|
||||
@@ -2024,7 +2012,7 @@ char AES_KEY_unwrap( const uint8_t* kek,
|
||||
* @param nonce a 128 bit string which is encrypted by AES_k
|
||||
* @param data buffer of input data
|
||||
* @param dataSize size of data in bytes
|
||||
* @param mac calculated CMAC hash
|
||||
* @param mac calculated Poly1305-AES mac
|
||||
*/
|
||||
void AES_Poly1305( const uint8_t* keys, const block_t nonce,
|
||||
const void* data, const size_t dataSize, block_t mac )
|
||||
@@ -2058,7 +2046,6 @@ void AES_Poly1305( const uint8_t* keys, const block_t nonce,
|
||||
BURN( RoundKey );
|
||||
addLBlocks( result, BLOCKSIZE, mac ); /* adding AES_k(nonce) */
|
||||
}
|
||||
#undef Np
|
||||
#endif /* POLY1305 */
|
||||
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ Refer to the BOTTOM OF THIS DOCUMENT for some explanations about these macros:
|
||||
|
||||
/**----------------------------------------------------------------------------
|
||||
Since stdint.h is not a part of ANSI-C, we used a 'trick' that should not cause
|
||||
any problems. You may replace the following two lines by: #include <stdint.h>
|
||||
any trouble. Yet the two lines below can be replaced by: #include <stdint.h>
|
||||
-----------------------------------------------------------------------------*/
|
||||
typedef unsigned char uint8_T;
|
||||
#define uint8_t uint8_T
|
||||
|
||||
Reference in New Issue
Block a user