merge cipher-aes C files in cryptonite
This commit is contained in:
parent
6ad51c0524
commit
6195bd40af
263
cbits/aes/aes_x86ni_impl.c
Normal file
263
cbits/aes/aes_x86ni_impl.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
void SIZED(aes_ni_encrypt_block)(aes_block *out, aes_key *key, aes_block *in)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
PRELOAD_ENC(k);
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
DO_ENC_BLOCK(m);
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_decrypt_block)(aes_block *out, aes_key *key, aes_block *in)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
PRELOAD_DEC(k);
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
DO_DEC_BLOCK(m);
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_encrypt_ecb)(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
|
||||
PRELOAD_ENC(k);
|
||||
for (; blocks-- > 0; in += 1, out += 1) {
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
DO_ENC_BLOCK(m);
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
}
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_decrypt_ecb)(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
|
||||
PRELOAD_DEC(k);
|
||||
|
||||
for (; blocks-- > 0; in += 1, out += 1) {
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
DO_DEC_BLOCK(m);
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
}
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_encrypt_cbc)(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
__m128i iv = _mm_loadu_si128((__m128i *) _iv);
|
||||
|
||||
PRELOAD_ENC(k);
|
||||
|
||||
for (; blocks-- > 0; in += 1, out += 1) {
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
m = _mm_xor_si128(m, iv);
|
||||
DO_ENC_BLOCK(m);
|
||||
iv = m;
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
}
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_decrypt_cbc)(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
__m128i iv = _mm_loadu_si128((__m128i *) _iv);
|
||||
|
||||
PRELOAD_DEC(k);
|
||||
|
||||
for (; blocks-- > 0; in += 1, out += 1) {
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
__m128i ivnext = m;
|
||||
|
||||
DO_DEC_BLOCK(m);
|
||||
m = _mm_xor_si128(m, iv);
|
||||
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
iv = ivnext;
|
||||
}
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_encrypt_ctr)(uint8_t *output, aes_key *key, aes_block *_iv, uint8_t *input, uint32_t len)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
__m128i bswap_mask = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8);
|
||||
__m128i one = _mm_set_epi32(0,1,0,0);
|
||||
uint32_t nb_blocks = len / 16;
|
||||
uint32_t part_block_len = len % 16;
|
||||
|
||||
/* get the IV in little endian format */
|
||||
__m128i iv = _mm_loadu_si128((__m128i *) _iv);
|
||||
iv = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
|
||||
PRELOAD_ENC(k);
|
||||
|
||||
for (; nb_blocks-- > 0; output += 16, input += 16) {
|
||||
/* put back the iv in big endian mode,
|
||||
* encrypt it and and xor it the input block
|
||||
*/
|
||||
__m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
DO_ENC_BLOCK(tmp);
|
||||
__m128i m = _mm_loadu_si128((__m128i *) input);
|
||||
m = _mm_xor_si128(m, tmp);
|
||||
|
||||
_mm_storeu_si128((__m128i *) output, m);
|
||||
/* iv += 1 */
|
||||
iv = _mm_add_epi64(iv, one);
|
||||
}
|
||||
|
||||
if (part_block_len != 0) {
|
||||
aes_block block;
|
||||
memset(&block.b, 0, 16);
|
||||
memcpy(&block.b, input, part_block_len);
|
||||
|
||||
__m128i m = _mm_loadu_si128((__m128i *) &block);
|
||||
__m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
|
||||
DO_ENC_BLOCK(tmp);
|
||||
m = _mm_xor_si128(m, tmp);
|
||||
_mm_storeu_si128((__m128i *) &block.b, m);
|
||||
memcpy(output, &block.b, part_block_len);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_encrypt_xts)(aes_block *out, aes_key *key1, aes_key *key2,
|
||||
aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks)
|
||||
{
|
||||
__m128i tweak = _mm_loadu_si128((__m128i *) _tweak);
|
||||
|
||||
do {
|
||||
__m128i *k2 = (__m128i *) key2->data;
|
||||
PRELOAD_ENC(k2);
|
||||
DO_ENC_BLOCK(tweak);
|
||||
|
||||
while (spoint-- > 0)
|
||||
tweak = gfmulx(tweak);
|
||||
} while (0) ;
|
||||
|
||||
do {
|
||||
__m128i *k1 = (__m128i *) key1->data;
|
||||
PRELOAD_ENC(k1);
|
||||
|
||||
for ( ; blocks-- > 0; in += 1, out += 1, tweak = gfmulx(tweak)) {
|
||||
__m128i m = _mm_loadu_si128((__m128i *) in);
|
||||
|
||||
m = _mm_xor_si128(m, tweak);
|
||||
DO_ENC_BLOCK(m);
|
||||
m = _mm_xor_si128(m, tweak);
|
||||
|
||||
_mm_storeu_si128((__m128i *) out, m);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
void SIZED(aes_ni_gcm_encrypt)(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
__m128i *k = (__m128i *) key->data;
|
||||
__m128i bswap_mask = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8);
|
||||
__m128i one = _mm_set_epi32(0,1,0,0);
|
||||
uint32_t nb_blocks = length / 16;
|
||||
uint32_t part_block_len = length % 16;
|
||||
|
||||
gcm->length_input += length;
|
||||
|
||||
__m128i h = _mm_loadu_si128((__m128i *) &gcm->h);
|
||||
__m128i tag = _mm_loadu_si128((__m128i *) &gcm->tag);
|
||||
__m128i iv = _mm_loadu_si128((__m128i *) &gcm->civ);
|
||||
iv = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
|
||||
PRELOAD_ENC(k);
|
||||
|
||||
for (; nb_blocks-- > 0; output += 16, input += 16) {
|
||||
/* iv += 1 */
|
||||
iv = _mm_add_epi64(iv, one);
|
||||
|
||||
/* put back iv in big endian, encrypt it,
|
||||
* and xor it to input */
|
||||
__m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
DO_ENC_BLOCK(tmp);
|
||||
__m128i m = _mm_loadu_si128((__m128i *) input);
|
||||
m = _mm_xor_si128(m, tmp);
|
||||
|
||||
tag = ghash_add(tag, h, m);
|
||||
|
||||
/* store it out */
|
||||
_mm_storeu_si128((__m128i *) output, m);
|
||||
}
|
||||
if (part_block_len > 0) {
|
||||
__m128i mask;
|
||||
aes_block block;
|
||||
/* FIXME could do something a bit more clever (slli & sub & and maybe) ... */
|
||||
switch (part_block_len) {
|
||||
case 1: mask = _mm_setr_epi8(0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 2: mask = _mm_setr_epi8(0,1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 3: mask = _mm_setr_epi8(0,1,2,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 4: mask = _mm_setr_epi8(0,1,2,3,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 5: mask = _mm_setr_epi8(0,1,2,3,4,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 6: mask = _mm_setr_epi8(0,1,2,3,4,5,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 7: mask = _mm_setr_epi8(0,1,2,3,4,5,6,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 8: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 9: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 10: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,0x80,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 11: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,0x80,0x80,0x80,0x80,0x80); break;
|
||||
case 12: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,0x80,0x80,0x80,0x80); break;
|
||||
case 13: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,0x80,0x80,0x80); break;
|
||||
case 14: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,0x80,0x80); break;
|
||||
case 15: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,0x80); break;
|
||||
default: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); break;
|
||||
}
|
||||
block128_zero(&block);
|
||||
block128_copy_bytes(&block, input, part_block_len);
|
||||
|
||||
/* iv += 1 */
|
||||
iv = _mm_add_epi64(iv, one);
|
||||
|
||||
/* put back iv in big endian mode, encrypt it and xor it with input */
|
||||
__m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
DO_ENC_BLOCK(tmp);
|
||||
|
||||
__m128i m = _mm_loadu_si128((__m128i *) &block);
|
||||
m = _mm_xor_si128(m, tmp);
|
||||
m = _mm_shuffle_epi8(m, mask);
|
||||
|
||||
tag = ghash_add(tag, h, m);
|
||||
|
||||
/* make output */
|
||||
_mm_storeu_si128((__m128i *) &block.b, m);
|
||||
memcpy(output, &block.b, part_block_len);
|
||||
}
|
||||
/* store back IV & tag */
|
||||
__m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);
|
||||
_mm_storeu_si128((__m128i *) &gcm->civ, tmp);
|
||||
_mm_storeu_si128((__m128i *) &gcm->tag, tag);
|
||||
}
|
||||
99
cbits/aes/block128.h
Normal file
99
cbits/aes/block128.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BLOCK128_H
|
||||
#define BLOCK128_H
|
||||
|
||||
#include <cryptonite_bitfn.h>
|
||||
|
||||
typedef union {
|
||||
uint64_t q[2];
|
||||
uint32_t d[4];
|
||||
uint16_t w[8];
|
||||
uint8_t b[16];
|
||||
} block128;
|
||||
|
||||
static inline void block128_copy_bytes(block128 *block, uint8_t *src, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) block->b[i] = src[i];
|
||||
}
|
||||
|
||||
static inline void block128_copy(block128 *d, const block128 *s)
|
||||
{
|
||||
d->q[0] = s->q[0]; d->q[1] = s->q[1];
|
||||
}
|
||||
|
||||
static inline void block128_zero(block128 *d)
|
||||
{
|
||||
d->q[0] = 0; d->q[1] = 0;
|
||||
}
|
||||
|
||||
static inline void block128_xor(block128 *d, const block128 *s)
|
||||
{
|
||||
d->q[0] ^= s->q[0];
|
||||
d->q[1] ^= s->q[1];
|
||||
}
|
||||
|
||||
static inline void block128_vxor(block128 *d, const block128 *s1, const block128 *s2)
|
||||
{
|
||||
d->q[0] = s1->q[0] ^ s2->q[0];
|
||||
d->q[1] = s1->q[1] ^ s2->q[1];
|
||||
}
|
||||
|
||||
static inline void block128_xor_bytes(block128 *block, uint8_t *src, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) block->b[i] ^= src[i];
|
||||
}
|
||||
|
||||
static inline void block128_inc_be(block128 *b)
|
||||
{
|
||||
uint64_t v = be64_to_cpu(b->q[1]);
|
||||
if (++v == 0) {
|
||||
b->q[0] = cpu_to_be64(be64_to_cpu(b->q[0]) + 1);
|
||||
b->q[1] = 0;
|
||||
} else
|
||||
b->q[1] = cpu_to_be64(v);
|
||||
}
|
||||
|
||||
#ifdef IMPL_DEBUG
|
||||
#include <stdio.h>
|
||||
static inline void block128_print(block128 *b)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02x ", b->b[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
442
cbits/aes/generic.c
Normal file
442
cbits/aes/generic.c
Normal file
@ -0,0 +1,442 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* AES implementation
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <cryptonite_aes.h>
|
||||
#include <cryptonite_bitfn.h>
|
||||
|
||||
static uint8_t sbox[256] = {
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe,
|
||||
0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4,
|
||||
0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7,
|
||||
0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3,
|
||||
0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09,
|
||||
0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3,
|
||||
0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe,
|
||||
0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92,
|
||||
0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,
|
||||
0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
|
||||
0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
|
||||
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2,
|
||||
0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5,
|
||||
0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25,
|
||||
0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86,
|
||||
0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,
|
||||
0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42,
|
||||
0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
static uint8_t rsbox[256] = {
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81,
|
||||
0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e,
|
||||
0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23,
|
||||
0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66,
|
||||
0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72,
|
||||
0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65,
|
||||
0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46,
|
||||
0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
|
||||
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca,
|
||||
0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91,
|
||||
0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
|
||||
0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
|
||||
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f,
|
||||
0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2,
|
||||
0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8,
|
||||
0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93,
|
||||
0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb,
|
||||
0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,
|
||||
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||
};
|
||||
|
||||
static uint8_t Rcon[] = {
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
|
||||
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
|
||||
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
|
||||
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb,
|
||||
};
|
||||
|
||||
#define G(a,b,c,d,e,f) { a,b,c,d,e,f }
|
||||
uint8_t gmtab[256][6] =
|
||||
{
|
||||
G(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), G(0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e),
|
||||
G(0x04, 0x06, 0x12, 0x16, 0x1a, 0x1c), G(0x06, 0x05, 0x1b, 0x1d, 0x17, 0x12),
|
||||
G(0x08, 0x0c, 0x24, 0x2c, 0x34, 0x38), G(0x0a, 0x0f, 0x2d, 0x27, 0x39, 0x36),
|
||||
G(0x0c, 0x0a, 0x36, 0x3a, 0x2e, 0x24), G(0x0e, 0x09, 0x3f, 0x31, 0x23, 0x2a),
|
||||
G(0x10, 0x18, 0x48, 0x58, 0x68, 0x70), G(0x12, 0x1b, 0x41, 0x53, 0x65, 0x7e),
|
||||
G(0x14, 0x1e, 0x5a, 0x4e, 0x72, 0x6c), G(0x16, 0x1d, 0x53, 0x45, 0x7f, 0x62),
|
||||
G(0x18, 0x14, 0x6c, 0x74, 0x5c, 0x48), G(0x1a, 0x17, 0x65, 0x7f, 0x51, 0x46),
|
||||
G(0x1c, 0x12, 0x7e, 0x62, 0x46, 0x54), G(0x1e, 0x11, 0x77, 0x69, 0x4b, 0x5a),
|
||||
G(0x20, 0x30, 0x90, 0xb0, 0xd0, 0xe0), G(0x22, 0x33, 0x99, 0xbb, 0xdd, 0xee),
|
||||
G(0x24, 0x36, 0x82, 0xa6, 0xca, 0xfc), G(0x26, 0x35, 0x8b, 0xad, 0xc7, 0xf2),
|
||||
G(0x28, 0x3c, 0xb4, 0x9c, 0xe4, 0xd8), G(0x2a, 0x3f, 0xbd, 0x97, 0xe9, 0xd6),
|
||||
G(0x2c, 0x3a, 0xa6, 0x8a, 0xfe, 0xc4), G(0x2e, 0x39, 0xaf, 0x81, 0xf3, 0xca),
|
||||
G(0x30, 0x28, 0xd8, 0xe8, 0xb8, 0x90), G(0x32, 0x2b, 0xd1, 0xe3, 0xb5, 0x9e),
|
||||
G(0x34, 0x2e, 0xca, 0xfe, 0xa2, 0x8c), G(0x36, 0x2d, 0xc3, 0xf5, 0xaf, 0x82),
|
||||
G(0x38, 0x24, 0xfc, 0xc4, 0x8c, 0xa8), G(0x3a, 0x27, 0xf5, 0xcf, 0x81, 0xa6),
|
||||
G(0x3c, 0x22, 0xee, 0xd2, 0x96, 0xb4), G(0x3e, 0x21, 0xe7, 0xd9, 0x9b, 0xba),
|
||||
G(0x40, 0x60, 0x3b, 0x7b, 0xbb, 0xdb), G(0x42, 0x63, 0x32, 0x70, 0xb6, 0xd5),
|
||||
G(0x44, 0x66, 0x29, 0x6d, 0xa1, 0xc7), G(0x46, 0x65, 0x20, 0x66, 0xac, 0xc9),
|
||||
G(0x48, 0x6c, 0x1f, 0x57, 0x8f, 0xe3), G(0x4a, 0x6f, 0x16, 0x5c, 0x82, 0xed),
|
||||
G(0x4c, 0x6a, 0x0d, 0x41, 0x95, 0xff), G(0x4e, 0x69, 0x04, 0x4a, 0x98, 0xf1),
|
||||
G(0x50, 0x78, 0x73, 0x23, 0xd3, 0xab), G(0x52, 0x7b, 0x7a, 0x28, 0xde, 0xa5),
|
||||
G(0x54, 0x7e, 0x61, 0x35, 0xc9, 0xb7), G(0x56, 0x7d, 0x68, 0x3e, 0xc4, 0xb9),
|
||||
G(0x58, 0x74, 0x57, 0x0f, 0xe7, 0x93), G(0x5a, 0x77, 0x5e, 0x04, 0xea, 0x9d),
|
||||
G(0x5c, 0x72, 0x45, 0x19, 0xfd, 0x8f), G(0x5e, 0x71, 0x4c, 0x12, 0xf0, 0x81),
|
||||
G(0x60, 0x50, 0xab, 0xcb, 0x6b, 0x3b), G(0x62, 0x53, 0xa2, 0xc0, 0x66, 0x35),
|
||||
G(0x64, 0x56, 0xb9, 0xdd, 0x71, 0x27), G(0x66, 0x55, 0xb0, 0xd6, 0x7c, 0x29),
|
||||
G(0x68, 0x5c, 0x8f, 0xe7, 0x5f, 0x03), G(0x6a, 0x5f, 0x86, 0xec, 0x52, 0x0d),
|
||||
G(0x6c, 0x5a, 0x9d, 0xf1, 0x45, 0x1f), G(0x6e, 0x59, 0x94, 0xfa, 0x48, 0x11),
|
||||
G(0x70, 0x48, 0xe3, 0x93, 0x03, 0x4b), G(0x72, 0x4b, 0xea, 0x98, 0x0e, 0x45),
|
||||
G(0x74, 0x4e, 0xf1, 0x85, 0x19, 0x57), G(0x76, 0x4d, 0xf8, 0x8e, 0x14, 0x59),
|
||||
G(0x78, 0x44, 0xc7, 0xbf, 0x37, 0x73), G(0x7a, 0x47, 0xce, 0xb4, 0x3a, 0x7d),
|
||||
G(0x7c, 0x42, 0xd5, 0xa9, 0x2d, 0x6f), G(0x7e, 0x41, 0xdc, 0xa2, 0x20, 0x61),
|
||||
G(0x80, 0xc0, 0x76, 0xf6, 0x6d, 0xad), G(0x82, 0xc3, 0x7f, 0xfd, 0x60, 0xa3),
|
||||
G(0x84, 0xc6, 0x64, 0xe0, 0x77, 0xb1), G(0x86, 0xc5, 0x6d, 0xeb, 0x7a, 0xbf),
|
||||
G(0x88, 0xcc, 0x52, 0xda, 0x59, 0x95), G(0x8a, 0xcf, 0x5b, 0xd1, 0x54, 0x9b),
|
||||
G(0x8c, 0xca, 0x40, 0xcc, 0x43, 0x89), G(0x8e, 0xc9, 0x49, 0xc7, 0x4e, 0x87),
|
||||
G(0x90, 0xd8, 0x3e, 0xae, 0x05, 0xdd), G(0x92, 0xdb, 0x37, 0xa5, 0x08, 0xd3),
|
||||
G(0x94, 0xde, 0x2c, 0xb8, 0x1f, 0xc1), G(0x96, 0xdd, 0x25, 0xb3, 0x12, 0xcf),
|
||||
G(0x98, 0xd4, 0x1a, 0x82, 0x31, 0xe5), G(0x9a, 0xd7, 0x13, 0x89, 0x3c, 0xeb),
|
||||
G(0x9c, 0xd2, 0x08, 0x94, 0x2b, 0xf9), G(0x9e, 0xd1, 0x01, 0x9f, 0x26, 0xf7),
|
||||
G(0xa0, 0xf0, 0xe6, 0x46, 0xbd, 0x4d), G(0xa2, 0xf3, 0xef, 0x4d, 0xb0, 0x43),
|
||||
G(0xa4, 0xf6, 0xf4, 0x50, 0xa7, 0x51), G(0xa6, 0xf5, 0xfd, 0x5b, 0xaa, 0x5f),
|
||||
G(0xa8, 0xfc, 0xc2, 0x6a, 0x89, 0x75), G(0xaa, 0xff, 0xcb, 0x61, 0x84, 0x7b),
|
||||
G(0xac, 0xfa, 0xd0, 0x7c, 0x93, 0x69), G(0xae, 0xf9, 0xd9, 0x77, 0x9e, 0x67),
|
||||
G(0xb0, 0xe8, 0xae, 0x1e, 0xd5, 0x3d), G(0xb2, 0xeb, 0xa7, 0x15, 0xd8, 0x33),
|
||||
G(0xb4, 0xee, 0xbc, 0x08, 0xcf, 0x21), G(0xb6, 0xed, 0xb5, 0x03, 0xc2, 0x2f),
|
||||
G(0xb8, 0xe4, 0x8a, 0x32, 0xe1, 0x05), G(0xba, 0xe7, 0x83, 0x39, 0xec, 0x0b),
|
||||
G(0xbc, 0xe2, 0x98, 0x24, 0xfb, 0x19), G(0xbe, 0xe1, 0x91, 0x2f, 0xf6, 0x17),
|
||||
G(0xc0, 0xa0, 0x4d, 0x8d, 0xd6, 0x76), G(0xc2, 0xa3, 0x44, 0x86, 0xdb, 0x78),
|
||||
G(0xc4, 0xa6, 0x5f, 0x9b, 0xcc, 0x6a), G(0xc6, 0xa5, 0x56, 0x90, 0xc1, 0x64),
|
||||
G(0xc8, 0xac, 0x69, 0xa1, 0xe2, 0x4e), G(0xca, 0xaf, 0x60, 0xaa, 0xef, 0x40),
|
||||
G(0xcc, 0xaa, 0x7b, 0xb7, 0xf8, 0x52), G(0xce, 0xa9, 0x72, 0xbc, 0xf5, 0x5c),
|
||||
G(0xd0, 0xb8, 0x05, 0xd5, 0xbe, 0x06), G(0xd2, 0xbb, 0x0c, 0xde, 0xb3, 0x08),
|
||||
G(0xd4, 0xbe, 0x17, 0xc3, 0xa4, 0x1a), G(0xd6, 0xbd, 0x1e, 0xc8, 0xa9, 0x14),
|
||||
G(0xd8, 0xb4, 0x21, 0xf9, 0x8a, 0x3e), G(0xda, 0xb7, 0x28, 0xf2, 0x87, 0x30),
|
||||
G(0xdc, 0xb2, 0x33, 0xef, 0x90, 0x22), G(0xde, 0xb1, 0x3a, 0xe4, 0x9d, 0x2c),
|
||||
G(0xe0, 0x90, 0xdd, 0x3d, 0x06, 0x96), G(0xe2, 0x93, 0xd4, 0x36, 0x0b, 0x98),
|
||||
G(0xe4, 0x96, 0xcf, 0x2b, 0x1c, 0x8a), G(0xe6, 0x95, 0xc6, 0x20, 0x11, 0x84),
|
||||
G(0xe8, 0x9c, 0xf9, 0x11, 0x32, 0xae), G(0xea, 0x9f, 0xf0, 0x1a, 0x3f, 0xa0),
|
||||
G(0xec, 0x9a, 0xeb, 0x07, 0x28, 0xb2), G(0xee, 0x99, 0xe2, 0x0c, 0x25, 0xbc),
|
||||
G(0xf0, 0x88, 0x95, 0x65, 0x6e, 0xe6), G(0xf2, 0x8b, 0x9c, 0x6e, 0x63, 0xe8),
|
||||
G(0xf4, 0x8e, 0x87, 0x73, 0x74, 0xfa), G(0xf6, 0x8d, 0x8e, 0x78, 0x79, 0xf4),
|
||||
G(0xf8, 0x84, 0xb1, 0x49, 0x5a, 0xde), G(0xfa, 0x87, 0xb8, 0x42, 0x57, 0xd0),
|
||||
G(0xfc, 0x82, 0xa3, 0x5f, 0x40, 0xc2), G(0xfe, 0x81, 0xaa, 0x54, 0x4d, 0xcc),
|
||||
G(0x1b, 0x9b, 0xec, 0xf7, 0xda, 0x41), G(0x19, 0x98, 0xe5, 0xfc, 0xd7, 0x4f),
|
||||
G(0x1f, 0x9d, 0xfe, 0xe1, 0xc0, 0x5d), G(0x1d, 0x9e, 0xf7, 0xea, 0xcd, 0x53),
|
||||
G(0x13, 0x97, 0xc8, 0xdb, 0xee, 0x79), G(0x11, 0x94, 0xc1, 0xd0, 0xe3, 0x77),
|
||||
G(0x17, 0x91, 0xda, 0xcd, 0xf4, 0x65), G(0x15, 0x92, 0xd3, 0xc6, 0xf9, 0x6b),
|
||||
G(0x0b, 0x83, 0xa4, 0xaf, 0xb2, 0x31), G(0x09, 0x80, 0xad, 0xa4, 0xbf, 0x3f),
|
||||
G(0x0f, 0x85, 0xb6, 0xb9, 0xa8, 0x2d), G(0x0d, 0x86, 0xbf, 0xb2, 0xa5, 0x23),
|
||||
G(0x03, 0x8f, 0x80, 0x83, 0x86, 0x09), G(0x01, 0x8c, 0x89, 0x88, 0x8b, 0x07),
|
||||
G(0x07, 0x89, 0x92, 0x95, 0x9c, 0x15), G(0x05, 0x8a, 0x9b, 0x9e, 0x91, 0x1b),
|
||||
G(0x3b, 0xab, 0x7c, 0x47, 0x0a, 0xa1), G(0x39, 0xa8, 0x75, 0x4c, 0x07, 0xaf),
|
||||
G(0x3f, 0xad, 0x6e, 0x51, 0x10, 0xbd), G(0x3d, 0xae, 0x67, 0x5a, 0x1d, 0xb3),
|
||||
G(0x33, 0xa7, 0x58, 0x6b, 0x3e, 0x99), G(0x31, 0xa4, 0x51, 0x60, 0x33, 0x97),
|
||||
G(0x37, 0xa1, 0x4a, 0x7d, 0x24, 0x85), G(0x35, 0xa2, 0x43, 0x76, 0x29, 0x8b),
|
||||
G(0x2b, 0xb3, 0x34, 0x1f, 0x62, 0xd1), G(0x29, 0xb0, 0x3d, 0x14, 0x6f, 0xdf),
|
||||
G(0x2f, 0xb5, 0x26, 0x09, 0x78, 0xcd), G(0x2d, 0xb6, 0x2f, 0x02, 0x75, 0xc3),
|
||||
G(0x23, 0xbf, 0x10, 0x33, 0x56, 0xe9), G(0x21, 0xbc, 0x19, 0x38, 0x5b, 0xe7),
|
||||
G(0x27, 0xb9, 0x02, 0x25, 0x4c, 0xf5), G(0x25, 0xba, 0x0b, 0x2e, 0x41, 0xfb),
|
||||
G(0x5b, 0xfb, 0xd7, 0x8c, 0x61, 0x9a), G(0x59, 0xf8, 0xde, 0x87, 0x6c, 0x94),
|
||||
G(0x5f, 0xfd, 0xc5, 0x9a, 0x7b, 0x86), G(0x5d, 0xfe, 0xcc, 0x91, 0x76, 0x88),
|
||||
G(0x53, 0xf7, 0xf3, 0xa0, 0x55, 0xa2), G(0x51, 0xf4, 0xfa, 0xab, 0x58, 0xac),
|
||||
G(0x57, 0xf1, 0xe1, 0xb6, 0x4f, 0xbe), G(0x55, 0xf2, 0xe8, 0xbd, 0x42, 0xb0),
|
||||
G(0x4b, 0xe3, 0x9f, 0xd4, 0x09, 0xea), G(0x49, 0xe0, 0x96, 0xdf, 0x04, 0xe4),
|
||||
G(0x4f, 0xe5, 0x8d, 0xc2, 0x13, 0xf6), G(0x4d, 0xe6, 0x84, 0xc9, 0x1e, 0xf8),
|
||||
G(0x43, 0xef, 0xbb, 0xf8, 0x3d, 0xd2), G(0x41, 0xec, 0xb2, 0xf3, 0x30, 0xdc),
|
||||
G(0x47, 0xe9, 0xa9, 0xee, 0x27, 0xce), G(0x45, 0xea, 0xa0, 0xe5, 0x2a, 0xc0),
|
||||
G(0x7b, 0xcb, 0x47, 0x3c, 0xb1, 0x7a), G(0x79, 0xc8, 0x4e, 0x37, 0xbc, 0x74),
|
||||
G(0x7f, 0xcd, 0x55, 0x2a, 0xab, 0x66), G(0x7d, 0xce, 0x5c, 0x21, 0xa6, 0x68),
|
||||
G(0x73, 0xc7, 0x63, 0x10, 0x85, 0x42), G(0x71, 0xc4, 0x6a, 0x1b, 0x88, 0x4c),
|
||||
G(0x77, 0xc1, 0x71, 0x06, 0x9f, 0x5e), G(0x75, 0xc2, 0x78, 0x0d, 0x92, 0x50),
|
||||
G(0x6b, 0xd3, 0x0f, 0x64, 0xd9, 0x0a), G(0x69, 0xd0, 0x06, 0x6f, 0xd4, 0x04),
|
||||
G(0x6f, 0xd5, 0x1d, 0x72, 0xc3, 0x16), G(0x6d, 0xd6, 0x14, 0x79, 0xce, 0x18),
|
||||
G(0x63, 0xdf, 0x2b, 0x48, 0xed, 0x32), G(0x61, 0xdc, 0x22, 0x43, 0xe0, 0x3c),
|
||||
G(0x67, 0xd9, 0x39, 0x5e, 0xf7, 0x2e), G(0x65, 0xda, 0x30, 0x55, 0xfa, 0x20),
|
||||
G(0x9b, 0x5b, 0x9a, 0x01, 0xb7, 0xec), G(0x99, 0x58, 0x93, 0x0a, 0xba, 0xe2),
|
||||
G(0x9f, 0x5d, 0x88, 0x17, 0xad, 0xf0), G(0x9d, 0x5e, 0x81, 0x1c, 0xa0, 0xfe),
|
||||
G(0x93, 0x57, 0xbe, 0x2d, 0x83, 0xd4), G(0x91, 0x54, 0xb7, 0x26, 0x8e, 0xda),
|
||||
G(0x97, 0x51, 0xac, 0x3b, 0x99, 0xc8), G(0x95, 0x52, 0xa5, 0x30, 0x94, 0xc6),
|
||||
G(0x8b, 0x43, 0xd2, 0x59, 0xdf, 0x9c), G(0x89, 0x40, 0xdb, 0x52, 0xd2, 0x92),
|
||||
G(0x8f, 0x45, 0xc0, 0x4f, 0xc5, 0x80), G(0x8d, 0x46, 0xc9, 0x44, 0xc8, 0x8e),
|
||||
G(0x83, 0x4f, 0xf6, 0x75, 0xeb, 0xa4), G(0x81, 0x4c, 0xff, 0x7e, 0xe6, 0xaa),
|
||||
G(0x87, 0x49, 0xe4, 0x63, 0xf1, 0xb8), G(0x85, 0x4a, 0xed, 0x68, 0xfc, 0xb6),
|
||||
G(0xbb, 0x6b, 0x0a, 0xb1, 0x67, 0x0c), G(0xb9, 0x68, 0x03, 0xba, 0x6a, 0x02),
|
||||
G(0xbf, 0x6d, 0x18, 0xa7, 0x7d, 0x10), G(0xbd, 0x6e, 0x11, 0xac, 0x70, 0x1e),
|
||||
G(0xb3, 0x67, 0x2e, 0x9d, 0x53, 0x34), G(0xb1, 0x64, 0x27, 0x96, 0x5e, 0x3a),
|
||||
G(0xb7, 0x61, 0x3c, 0x8b, 0x49, 0x28), G(0xb5, 0x62, 0x35, 0x80, 0x44, 0x26),
|
||||
G(0xab, 0x73, 0x42, 0xe9, 0x0f, 0x7c), G(0xa9, 0x70, 0x4b, 0xe2, 0x02, 0x72),
|
||||
G(0xaf, 0x75, 0x50, 0xff, 0x15, 0x60), G(0xad, 0x76, 0x59, 0xf4, 0x18, 0x6e),
|
||||
G(0xa3, 0x7f, 0x66, 0xc5, 0x3b, 0x44), G(0xa1, 0x7c, 0x6f, 0xce, 0x36, 0x4a),
|
||||
G(0xa7, 0x79, 0x74, 0xd3, 0x21, 0x58), G(0xa5, 0x7a, 0x7d, 0xd8, 0x2c, 0x56),
|
||||
G(0xdb, 0x3b, 0xa1, 0x7a, 0x0c, 0x37), G(0xd9, 0x38, 0xa8, 0x71, 0x01, 0x39),
|
||||
G(0xdf, 0x3d, 0xb3, 0x6c, 0x16, 0x2b), G(0xdd, 0x3e, 0xba, 0x67, 0x1b, 0x25),
|
||||
G(0xd3, 0x37, 0x85, 0x56, 0x38, 0x0f), G(0xd1, 0x34, 0x8c, 0x5d, 0x35, 0x01),
|
||||
G(0xd7, 0x31, 0x97, 0x40, 0x22, 0x13), G(0xd5, 0x32, 0x9e, 0x4b, 0x2f, 0x1d),
|
||||
G(0xcb, 0x23, 0xe9, 0x22, 0x64, 0x47), G(0xc9, 0x20, 0xe0, 0x29, 0x69, 0x49),
|
||||
G(0xcf, 0x25, 0xfb, 0x34, 0x7e, 0x5b), G(0xcd, 0x26, 0xf2, 0x3f, 0x73, 0x55),
|
||||
G(0xc3, 0x2f, 0xcd, 0x0e, 0x50, 0x7f), G(0xc1, 0x2c, 0xc4, 0x05, 0x5d, 0x71),
|
||||
G(0xc7, 0x29, 0xdf, 0x18, 0x4a, 0x63), G(0xc5, 0x2a, 0xd6, 0x13, 0x47, 0x6d),
|
||||
G(0xfb, 0x0b, 0x31, 0xca, 0xdc, 0xd7), G(0xf9, 0x08, 0x38, 0xc1, 0xd1, 0xd9),
|
||||
G(0xff, 0x0d, 0x23, 0xdc, 0xc6, 0xcb), G(0xfd, 0x0e, 0x2a, 0xd7, 0xcb, 0xc5),
|
||||
G(0xf3, 0x07, 0x15, 0xe6, 0xe8, 0xef), G(0xf1, 0x04, 0x1c, 0xed, 0xe5, 0xe1),
|
||||
G(0xf7, 0x01, 0x07, 0xf0, 0xf2, 0xf3), G(0xf5, 0x02, 0x0e, 0xfb, 0xff, 0xfd),
|
||||
G(0xeb, 0x13, 0x79, 0x92, 0xb4, 0xa7), G(0xe9, 0x10, 0x70, 0x99, 0xb9, 0xa9),
|
||||
G(0xef, 0x15, 0x6b, 0x84, 0xae, 0xbb), G(0xed, 0x16, 0x62, 0x8f, 0xa3, 0xb5),
|
||||
G(0xe3, 0x1f, 0x5d, 0xbe, 0x80, 0x9f), G(0xe1, 0x1c, 0x54, 0xb5, 0x8d, 0x91),
|
||||
G(0xe7, 0x19, 0x4f, 0xa8, 0x9a, 0x83), G(0xe5, 0x1a, 0x46, 0xa3, 0x97, 0x8d),
|
||||
};
|
||||
#undef G
|
||||
|
||||
static void expand_key(uint8_t *expandedKey, uint8_t *key, int size, size_t expandedKeySize)
|
||||
{
|
||||
int csz;
|
||||
int i;
|
||||
uint8_t t[4] = { 0 };
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
expandedKey[i] = key[i];
|
||||
csz = size;
|
||||
|
||||
i = 1;
|
||||
while (csz < expandedKeySize) {
|
||||
t[0] = expandedKey[(csz - 4) + 0];
|
||||
t[1] = expandedKey[(csz - 4) + 1];
|
||||
t[2] = expandedKey[(csz - 4) + 2];
|
||||
t[3] = expandedKey[(csz - 4) + 3];
|
||||
|
||||
if (csz % size == 0) {
|
||||
uint8_t tmp;
|
||||
|
||||
tmp = t[0];
|
||||
t[0] = sbox[t[1]] ^ Rcon[i++ % sizeof(Rcon)];
|
||||
t[1] = sbox[t[2]];
|
||||
t[2] = sbox[t[3]];
|
||||
t[3] = sbox[tmp];
|
||||
}
|
||||
|
||||
if (size == 32 && ((csz % size) == 16)) {
|
||||
t[0] = sbox[t[0]];
|
||||
t[1] = sbox[t[1]];
|
||||
t[2] = sbox[t[2]];
|
||||
t[3] = sbox[t[3]];
|
||||
}
|
||||
|
||||
expandedKey[csz] = expandedKey[csz - size] ^ t[0]; csz++;
|
||||
expandedKey[csz] = expandedKey[csz - size] ^ t[1]; csz++;
|
||||
expandedKey[csz] = expandedKey[csz - size] ^ t[2]; csz++;
|
||||
expandedKey[csz] = expandedKey[csz - size] ^ t[3]; csz++;
|
||||
}
|
||||
}
|
||||
|
||||
static void shift_rows(uint8_t *state)
|
||||
{
|
||||
uint32_t *s32;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
state[i] = sbox[state[i]];
|
||||
s32 = (uint32_t *) state;
|
||||
s32[1] = rol32_be(s32[1], 8);
|
||||
s32[2] = rol32_be(s32[2], 16);
|
||||
s32[3] = rol32_be(s32[3], 24);
|
||||
}
|
||||
|
||||
static void add_round_key(uint8_t *state, uint8_t *rk)
|
||||
{
|
||||
uint32_t *s32, *r32;
|
||||
|
||||
s32 = (uint32_t *) state;
|
||||
r32 = (uint32_t *) rk;
|
||||
s32[0] ^= r32[0];
|
||||
s32[1] ^= r32[1];
|
||||
s32[2] ^= r32[2];
|
||||
s32[3] ^= r32[3];
|
||||
}
|
||||
|
||||
#define gm1(a) (a)
|
||||
#define gm2(a) gmtab[a][0]
|
||||
#define gm3(a) gmtab[a][1]
|
||||
#define gm9(a) gmtab[a][2]
|
||||
#define gm11(a) gmtab[a][3]
|
||||
#define gm13(a) gmtab[a][4]
|
||||
#define gm14(a) gmtab[a][5]
|
||||
|
||||
static void mix_columns(uint8_t *state)
|
||||
{
|
||||
int i;
|
||||
uint8_t cpy[4];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
cpy[0] = state[0 * 4 + i];
|
||||
cpy[1] = state[1 * 4 + i];
|
||||
cpy[2] = state[2 * 4 + i];
|
||||
cpy[3] = state[3 * 4 + i];
|
||||
state[i] = gm2(cpy[0]) ^ gm1(cpy[3]) ^ gm1(cpy[2]) ^ gm3(cpy[1]);
|
||||
state[4+i] = gm2(cpy[1]) ^ gm1(cpy[0]) ^ gm1(cpy[3]) ^ gm3(cpy[2]);
|
||||
state[8+i] = gm2(cpy[2]) ^ gm1(cpy[1]) ^ gm1(cpy[0]) ^ gm3(cpy[3]);
|
||||
state[12+i] = gm2(cpy[3]) ^ gm1(cpy[2]) ^ gm1(cpy[1]) ^ gm3(cpy[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void create_round_key(uint8_t *expandedKey, uint8_t *rk)
|
||||
{
|
||||
int i,j;
|
||||
for (i = 0; i < 4; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
rk[i + j * 4] = expandedKey[i * 4 + j];
|
||||
}
|
||||
|
||||
static void aes_main(aes_key *key, uint8_t *state)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t rk[16];
|
||||
|
||||
create_round_key(key->data, rk);
|
||||
add_round_key(state, rk);
|
||||
|
||||
for (i = 1; i < key->nbr; i++) {
|
||||
create_round_key(key->data + 16 * i, rk);
|
||||
shift_rows(state);
|
||||
mix_columns(state);
|
||||
add_round_key(state, rk);
|
||||
}
|
||||
|
||||
create_round_key(key->data + 16 * key->nbr, rk);
|
||||
shift_rows(state);
|
||||
add_round_key(state, rk);
|
||||
}
|
||||
|
||||
static void shift_rows_inv(uint8_t *state)
|
||||
{
|
||||
uint32_t *s32;
|
||||
int i;
|
||||
|
||||
s32 = (uint32_t *) state;
|
||||
s32[1] = ror32_be(s32[1], 8);
|
||||
s32[2] = ror32_be(s32[2], 16);
|
||||
s32[3] = ror32_be(s32[3], 24);
|
||||
for (i = 0; i < 16; i++)
|
||||
state[i] = rsbox[state[i]];
|
||||
}
|
||||
|
||||
static void mix_columns_inv(uint8_t *state)
|
||||
{
|
||||
int i;
|
||||
uint8_t cpy[4];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
cpy[0] = state[0 * 4 + i];
|
||||
cpy[1] = state[1 * 4 + i];
|
||||
cpy[2] = state[2 * 4 + i];
|
||||
cpy[3] = state[3 * 4 + i];
|
||||
state[i] = gm14(cpy[0]) ^ gm9(cpy[3]) ^ gm13(cpy[2]) ^ gm11(cpy[1]);
|
||||
state[4+i] = gm14(cpy[1]) ^ gm9(cpy[0]) ^ gm13(cpy[3]) ^ gm11(cpy[2]);
|
||||
state[8+i] = gm14(cpy[2]) ^ gm9(cpy[1]) ^ gm13(cpy[0]) ^ gm11(cpy[3]);
|
||||
state[12+i] = gm14(cpy[3]) ^ gm9(cpy[2]) ^ gm13(cpy[1]) ^ gm11(cpy[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void aes_main_inv(aes_key *key, uint8_t *state)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t rk[16];
|
||||
|
||||
create_round_key(key->data + 16 * key->nbr, rk);
|
||||
add_round_key(state, rk);
|
||||
|
||||
for (i = key->nbr - 1; i > 0; i--) {
|
||||
create_round_key(key->data + 16 * i, rk);
|
||||
shift_rows_inv(state);
|
||||
add_round_key(state, rk);
|
||||
mix_columns_inv(state);
|
||||
}
|
||||
|
||||
create_round_key(key->data, rk);
|
||||
shift_rows_inv(state);
|
||||
add_round_key(state, rk);
|
||||
}
|
||||
|
||||
/* Set the block values, for the block:
|
||||
* a0,0 a0,1 a0,2 a0,3
|
||||
* a1,0 a1,1 a1,2 a1,3 -> a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
|
||||
* a2,0 a2,1 a2,2 a2,3
|
||||
* a3,0 a3,1 a3,2 a3,3
|
||||
*/
|
||||
#define swap_block(t, f) \
|
||||
t[0] = f[0]; t[4] = f[1]; t[8] = f[2]; t[12] = f[3]; \
|
||||
t[1] = f[4]; t[5] = f[5]; t[9] = f[6]; t[13] = f[7]; \
|
||||
t[2] = f[8]; t[6] = f[9]; t[10] = f[10]; t[14] = f[11]; \
|
||||
t[3] = f[12]; t[7] = f[13]; t[11] = f[14]; t[15] = f[15]
|
||||
|
||||
void cryptonite_aes_generic_encrypt_block(aes_block *output, aes_key *key, aes_block *input)
|
||||
{
|
||||
uint8_t block[16];
|
||||
uint8_t *iptr, *optr;
|
||||
|
||||
iptr = (uint8_t *) input;
|
||||
optr = (uint8_t *) output;
|
||||
swap_block(block, iptr);
|
||||
aes_main(key, block);
|
||||
swap_block(optr, block);
|
||||
}
|
||||
|
||||
void cryptonite_aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input)
|
||||
{
|
||||
uint8_t block[16];
|
||||
uint8_t *iptr, *optr;
|
||||
|
||||
iptr = (uint8_t *) input;
|
||||
optr = (uint8_t *) output;
|
||||
swap_block(block, iptr);
|
||||
aes_main_inv(key, block);
|
||||
swap_block(optr, block);
|
||||
}
|
||||
|
||||
void cryptonite_aes_generic_init(aes_key *key, uint8_t *origkey, uint8_t size)
|
||||
{
|
||||
int esz;
|
||||
|
||||
switch (size) {
|
||||
case 16: key->nbr = 10; esz = 176; break;
|
||||
case 24: key->nbr = 12; esz = 208; break;
|
||||
case 32: key->nbr = 14; esz = 240; break;
|
||||
default: return;
|
||||
}
|
||||
expand_key(key->data, origkey, size, esz);
|
||||
return;
|
||||
}
|
||||
34
cbits/aes/generic.h
Normal file
34
cbits/aes/generic.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "cryptonite_aes.h"
|
||||
|
||||
void aes_generic_encrypt_block(aes_block *output, aes_key *key, aes_block *input);
|
||||
void aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input);
|
||||
void aes_generic_init(aes_key *key, uint8_t *origkey, uint8_t size);
|
||||
72
cbits/aes/gf.c
Normal file
72
cbits/aes/gf.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <cryptonite_cpu.h>
|
||||
#include <aes/gf.h>
|
||||
#include <aes/x86ni.h>
|
||||
|
||||
/* this is a really inefficient way to GF multiply.
|
||||
* the alternative without hw accel is building small tables
|
||||
* to speed up the multiplication.
|
||||
* TODO: optimise with tables
|
||||
*/
|
||||
void gf_mul(block128 *a, block128 *b)
|
||||
{
|
||||
uint64_t a0, a1, v0, v1;
|
||||
int i, j;
|
||||
|
||||
a0 = a1 = 0;
|
||||
v0 = cpu_to_be64(a->q[0]);
|
||||
v1 = cpu_to_be64(a->q[1]);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (j = 0x80; j != 0; j >>= 1) {
|
||||
uint8_t x = b->b[i] & j;
|
||||
a0 ^= x ? v0 : 0;
|
||||
a1 ^= x ? v1 : 0;
|
||||
x = (uint8_t) v1 & 1;
|
||||
v1 = (v1 >> 1) | (v0 << 63);
|
||||
v0 = (v0 >> 1) ^ (x ? (0xe1ULL << 56) : 0);
|
||||
}
|
||||
a->q[0] = cpu_to_be64(a0);
|
||||
a->q[1] = cpu_to_be64(a1);
|
||||
}
|
||||
|
||||
/* inplace GFMUL for xts mode */
|
||||
void gf_mulx(block128 *a)
|
||||
{
|
||||
const uint64_t gf_mask = cpu_to_le64(0x8000000000000000ULL);
|
||||
uint64_t r = ((a->q[1] & gf_mask) ? cpu_to_le64(0x87) : 0);
|
||||
a->q[1] = cpu_to_le64((le64_to_cpu(a->q[1]) << 1) | (a->q[0] & gf_mask ? 1 : 0));
|
||||
a->q[0] = cpu_to_le64(le64_to_cpu(a->q[0]) << 1) ^ r;
|
||||
}
|
||||
|
||||
38
cbits/aes/gf.h
Normal file
38
cbits/aes/gf.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef CRYPTONITE_AES_GF128MUL_H
|
||||
#define CRYPTONITE_AES_GF128MUL_H
|
||||
|
||||
#include "aes/block128.h"
|
||||
|
||||
void gf_mul(block128 *a, block128 *b);
|
||||
void gf_mulx(block128 *a);
|
||||
|
||||
#endif
|
||||
331
cbits/aes/x86ni.c
Normal file
331
cbits/aes/x86ni.c
Normal file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef WITH_AESNI
|
||||
|
||||
#include <wmmintrin.h>
|
||||
#include <tmmintrin.h>
|
||||
#include <string.h>
|
||||
#include <cryptonite_aes.h>
|
||||
#include <cryptonite_cpu.h>
|
||||
#include <aes/x86ni.h>
|
||||
#include <aes/block128.h>
|
||||
|
||||
#ifdef ARCH_X86
|
||||
#define ALIGN_UP(addr, size) (((addr) + ((size) - 1)) & (~((size) - 1)))
|
||||
#define ALIGNMENT(n) __attribute__((aligned(n)))
|
||||
|
||||
/* old GCC version doesn't cope with the shuffle parameters, that can take 2 values (0xff and 0xaa)
|
||||
* in our case, passed as argument despite being a immediate 8 bits constant anyway.
|
||||
* un-factorise aes_128_key_expansion into 2 version that have the shuffle parameter explicitly set */
|
||||
static __m128i aes_128_key_expansion_ff(__m128i key, __m128i keygened)
|
||||
{
|
||||
keygened = _mm_shuffle_epi32(keygened, 0xff);
|
||||
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
|
||||
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
|
||||
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
|
||||
return _mm_xor_si128(key, keygened);
|
||||
}
|
||||
|
||||
static __m128i aes_128_key_expansion_aa(__m128i key, __m128i keygened)
|
||||
{
|
||||
keygened = _mm_shuffle_epi32(keygened, 0xaa);
|
||||
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
|
||||
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
|
||||
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
|
||||
return _mm_xor_si128(key, keygened);
|
||||
}
|
||||
|
||||
void aes_ni_init(aes_key *key, uint8_t *ikey, uint8_t size)
|
||||
{
|
||||
__m128i k[28];
|
||||
uint64_t *out = (uint64_t *) key->data;
|
||||
int i;
|
||||
|
||||
switch (size) {
|
||||
case 16:
|
||||
k[0] = _mm_loadu_si128((const __m128i*) ikey);
|
||||
|
||||
#define AES_128_key_exp(K, RCON) aes_128_key_expansion_ff(K, _mm_aeskeygenassist_si128(K, RCON))
|
||||
k[1] = AES_128_key_exp(k[0], 0x01);
|
||||
k[2] = AES_128_key_exp(k[1], 0x02);
|
||||
k[3] = AES_128_key_exp(k[2], 0x04);
|
||||
k[4] = AES_128_key_exp(k[3], 0x08);
|
||||
k[5] = AES_128_key_exp(k[4], 0x10);
|
||||
k[6] = AES_128_key_exp(k[5], 0x20);
|
||||
k[7] = AES_128_key_exp(k[6], 0x40);
|
||||
k[8] = AES_128_key_exp(k[7], 0x80);
|
||||
k[9] = AES_128_key_exp(k[8], 0x1B);
|
||||
k[10] = AES_128_key_exp(k[9], 0x36);
|
||||
|
||||
/* generate decryption keys in reverse order.
|
||||
* k[10] is shared by last encryption and first decryption rounds
|
||||
* k[20] is shared by first encryption round (and is the original user key) */
|
||||
k[11] = _mm_aesimc_si128(k[9]);
|
||||
k[12] = _mm_aesimc_si128(k[8]);
|
||||
k[13] = _mm_aesimc_si128(k[7]);
|
||||
k[14] = _mm_aesimc_si128(k[6]);
|
||||
k[15] = _mm_aesimc_si128(k[5]);
|
||||
k[16] = _mm_aesimc_si128(k[4]);
|
||||
k[17] = _mm_aesimc_si128(k[3]);
|
||||
k[18] = _mm_aesimc_si128(k[2]);
|
||||
k[19] = _mm_aesimc_si128(k[1]);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
_mm_storeu_si128(((__m128i *) out) + i, k[i]);
|
||||
break;
|
||||
case 32:
|
||||
#define AES_256_key_exp_1(K1, K2, RCON) aes_128_key_expansion_ff(K1, _mm_aeskeygenassist_si128(K2, RCON))
|
||||
#define AES_256_key_exp_2(K1, K2) aes_128_key_expansion_aa(K1, _mm_aeskeygenassist_si128(K2, 0x00))
|
||||
k[0] = _mm_loadu_si128((const __m128i*) ikey);
|
||||
k[1] = _mm_loadu_si128((const __m128i*) (ikey+16));
|
||||
k[2] = AES_256_key_exp_1(k[0], k[1], 0x01);
|
||||
k[3] = AES_256_key_exp_2(k[1], k[2]);
|
||||
k[4] = AES_256_key_exp_1(k[2], k[3], 0x02);
|
||||
k[5] = AES_256_key_exp_2(k[3], k[4]);
|
||||
k[6] = AES_256_key_exp_1(k[4], k[5], 0x04);
|
||||
k[7] = AES_256_key_exp_2(k[5], k[6]);
|
||||
k[8] = AES_256_key_exp_1(k[6], k[7], 0x08);
|
||||
k[9] = AES_256_key_exp_2(k[7], k[8]);
|
||||
k[10] = AES_256_key_exp_1(k[8], k[9], 0x10);
|
||||
k[11] = AES_256_key_exp_2(k[9], k[10]);
|
||||
k[12] = AES_256_key_exp_1(k[10], k[11], 0x20);
|
||||
k[13] = AES_256_key_exp_2(k[11], k[12]);
|
||||
k[14] = AES_256_key_exp_1(k[12], k[13], 0x40);
|
||||
|
||||
k[15] = _mm_aesimc_si128(k[13]);
|
||||
k[16] = _mm_aesimc_si128(k[12]);
|
||||
k[17] = _mm_aesimc_si128(k[11]);
|
||||
k[18] = _mm_aesimc_si128(k[10]);
|
||||
k[19] = _mm_aesimc_si128(k[9]);
|
||||
k[20] = _mm_aesimc_si128(k[8]);
|
||||
k[21] = _mm_aesimc_si128(k[7]);
|
||||
k[22] = _mm_aesimc_si128(k[6]);
|
||||
k[23] = _mm_aesimc_si128(k[5]);
|
||||
k[24] = _mm_aesimc_si128(k[4]);
|
||||
k[25] = _mm_aesimc_si128(k[3]);
|
||||
k[26] = _mm_aesimc_si128(k[2]);
|
||||
k[27] = _mm_aesimc_si128(k[1]);
|
||||
for (i = 0; i < 28; i++)
|
||||
_mm_storeu_si128(((__m128i *) out) + i, k[i]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* TO OPTIMISE: use pcmulqdq... or some faster code.
|
||||
* this is the lamest way of doing it, but i'm out of time.
|
||||
* this is basically a copy of gf_mulx in gf.c */
|
||||
static __m128i gfmulx(__m128i v)
|
||||
{
|
||||
uint64_t v_[2] ALIGNMENT(16);
|
||||
const uint64_t gf_mask = 0x8000000000000000;
|
||||
|
||||
_mm_store_si128((__m128i *) v_, v);
|
||||
uint64_t r = ((v_[1] & gf_mask) ? 0x87 : 0);
|
||||
v_[1] = (v_[1] << 1) | (v_[0] & gf_mask ? 1 : 0);
|
||||
v_[0] = (v_[0] << 1) ^ r;
|
||||
v = _mm_load_si128((__m128i *) v_);
|
||||
return v;
|
||||
}
|
||||
|
||||
static void unopt_gf_mul(block128 *a, block128 *b)
|
||||
{
|
||||
uint64_t a0, a1, v0, v1;
|
||||
int i, j;
|
||||
|
||||
a0 = a1 = 0;
|
||||
v0 = cpu_to_be64(a->q[0]);
|
||||
v1 = cpu_to_be64(a->q[1]);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (j = 0x80; j != 0; j >>= 1) {
|
||||
uint8_t x = b->b[i] & j;
|
||||
a0 ^= x ? v0 : 0;
|
||||
a1 ^= x ? v1 : 0;
|
||||
x = (uint8_t) v1 & 1;
|
||||
v1 = (v1 >> 1) | (v0 << 63);
|
||||
v0 = (v0 >> 1) ^ (x ? (0xe1ULL << 56) : 0);
|
||||
}
|
||||
a->q[0] = cpu_to_be64(a0);
|
||||
a->q[1] = cpu_to_be64(a1);
|
||||
}
|
||||
|
||||
static __m128i ghash_add(__m128i tag, __m128i h, __m128i m)
|
||||
{
|
||||
aes_block _t, _h;
|
||||
tag = _mm_xor_si128(tag, m);
|
||||
|
||||
_mm_store_si128((__m128i *) &_t, tag);
|
||||
_mm_store_si128((__m128i *) &_h, h);
|
||||
unopt_gf_mul(&_t, &_h);
|
||||
tag = _mm_load_si128((__m128i *) &_t);
|
||||
return tag;
|
||||
}
|
||||
|
||||
#define PRELOAD_ENC_KEYS128(k) \
|
||||
__m128i K0 = _mm_loadu_si128(((__m128i *) k)+0); \
|
||||
__m128i K1 = _mm_loadu_si128(((__m128i *) k)+1); \
|
||||
__m128i K2 = _mm_loadu_si128(((__m128i *) k)+2); \
|
||||
__m128i K3 = _mm_loadu_si128(((__m128i *) k)+3); \
|
||||
__m128i K4 = _mm_loadu_si128(((__m128i *) k)+4); \
|
||||
__m128i K5 = _mm_loadu_si128(((__m128i *) k)+5); \
|
||||
__m128i K6 = _mm_loadu_si128(((__m128i *) k)+6); \
|
||||
__m128i K7 = _mm_loadu_si128(((__m128i *) k)+7); \
|
||||
__m128i K8 = _mm_loadu_si128(((__m128i *) k)+8); \
|
||||
__m128i K9 = _mm_loadu_si128(((__m128i *) k)+9); \
|
||||
__m128i K10 = _mm_loadu_si128(((__m128i *) k)+10);
|
||||
|
||||
#define PRELOAD_ENC_KEYS256(k) \
|
||||
PRELOAD_ENC_KEYS128(k) \
|
||||
__m128i K11 = _mm_loadu_si128(((__m128i *) k)+11); \
|
||||
__m128i K12 = _mm_loadu_si128(((__m128i *) k)+12); \
|
||||
__m128i K13 = _mm_loadu_si128(((__m128i *) k)+13); \
|
||||
__m128i K14 = _mm_loadu_si128(((__m128i *) k)+14);
|
||||
|
||||
#define DO_ENC_BLOCK128(m) \
|
||||
m = _mm_xor_si128(m, K0); \
|
||||
m = _mm_aesenc_si128(m, K1); \
|
||||
m = _mm_aesenc_si128(m, K2); \
|
||||
m = _mm_aesenc_si128(m, K3); \
|
||||
m = _mm_aesenc_si128(m, K4); \
|
||||
m = _mm_aesenc_si128(m, K5); \
|
||||
m = _mm_aesenc_si128(m, K6); \
|
||||
m = _mm_aesenc_si128(m, K7); \
|
||||
m = _mm_aesenc_si128(m, K8); \
|
||||
m = _mm_aesenc_si128(m, K9); \
|
||||
m = _mm_aesenclast_si128(m, K10);
|
||||
|
||||
#define DO_ENC_BLOCK256(m) \
|
||||
m = _mm_xor_si128(m, K0); \
|
||||
m = _mm_aesenc_si128(m, K1); \
|
||||
m = _mm_aesenc_si128(m, K2); \
|
||||
m = _mm_aesenc_si128(m, K3); \
|
||||
m = _mm_aesenc_si128(m, K4); \
|
||||
m = _mm_aesenc_si128(m, K5); \
|
||||
m = _mm_aesenc_si128(m, K6); \
|
||||
m = _mm_aesenc_si128(m, K7); \
|
||||
m = _mm_aesenc_si128(m, K8); \
|
||||
m = _mm_aesenc_si128(m, K9); \
|
||||
m = _mm_aesenc_si128(m, K10); \
|
||||
m = _mm_aesenc_si128(m, K11); \
|
||||
m = _mm_aesenc_si128(m, K12); \
|
||||
m = _mm_aesenc_si128(m, K13); \
|
||||
m = _mm_aesenclast_si128(m, K14);
|
||||
|
||||
/* load K0 at K9 from index 'at' */
|
||||
#define PRELOAD_DEC_KEYS_AT(k, at) \
|
||||
__m128i K0 = _mm_loadu_si128(((__m128i *) k)+at+0); \
|
||||
__m128i K1 = _mm_loadu_si128(((__m128i *) k)+at+1); \
|
||||
__m128i K2 = _mm_loadu_si128(((__m128i *) k)+at+2); \
|
||||
__m128i K3 = _mm_loadu_si128(((__m128i *) k)+at+3); \
|
||||
__m128i K4 = _mm_loadu_si128(((__m128i *) k)+at+4); \
|
||||
__m128i K5 = _mm_loadu_si128(((__m128i *) k)+at+5); \
|
||||
__m128i K6 = _mm_loadu_si128(((__m128i *) k)+at+6); \
|
||||
__m128i K7 = _mm_loadu_si128(((__m128i *) k)+at+7); \
|
||||
__m128i K8 = _mm_loadu_si128(((__m128i *) k)+at+8); \
|
||||
__m128i K9 = _mm_loadu_si128(((__m128i *) k)+at+9); \
|
||||
|
||||
#define PRELOAD_DEC_KEYS128(k) \
|
||||
PRELOAD_DEC_KEYS_AT(k, 10) \
|
||||
__m128i K10 = _mm_loadu_si128(((__m128i *) k)+0);
|
||||
|
||||
#define PRELOAD_DEC_KEYS256(k) \
|
||||
PRELOAD_DEC_KEYS_AT(k, 14) \
|
||||
__m128i K10 = _mm_loadu_si128(((__m128i *) k)+14+10); \
|
||||
__m128i K11 = _mm_loadu_si128(((__m128i *) k)+14+11); \
|
||||
__m128i K12 = _mm_loadu_si128(((__m128i *) k)+14+12); \
|
||||
__m128i K13 = _mm_loadu_si128(((__m128i *) k)+14+13); \
|
||||
__m128i K14 = _mm_loadu_si128(((__m128i *) k)+0);
|
||||
|
||||
#define DO_DEC_BLOCK128(m) \
|
||||
m = _mm_xor_si128(m, K0); \
|
||||
m = _mm_aesdec_si128(m, K1); \
|
||||
m = _mm_aesdec_si128(m, K2); \
|
||||
m = _mm_aesdec_si128(m, K3); \
|
||||
m = _mm_aesdec_si128(m, K4); \
|
||||
m = _mm_aesdec_si128(m, K5); \
|
||||
m = _mm_aesdec_si128(m, K6); \
|
||||
m = _mm_aesdec_si128(m, K7); \
|
||||
m = _mm_aesdec_si128(m, K8); \
|
||||
m = _mm_aesdec_si128(m, K9); \
|
||||
m = _mm_aesdeclast_si128(m, K10);
|
||||
|
||||
#define DO_DEC_BLOCK256(m) \
|
||||
m = _mm_xor_si128(m, K0); \
|
||||
m = _mm_aesdec_si128(m, K1); \
|
||||
m = _mm_aesdec_si128(m, K2); \
|
||||
m = _mm_aesdec_si128(m, K3); \
|
||||
m = _mm_aesdec_si128(m, K4); \
|
||||
m = _mm_aesdec_si128(m, K5); \
|
||||
m = _mm_aesdec_si128(m, K6); \
|
||||
m = _mm_aesdec_si128(m, K7); \
|
||||
m = _mm_aesdec_si128(m, K8); \
|
||||
m = _mm_aesdec_si128(m, K9); \
|
||||
m = _mm_aesdec_si128(m, K10); \
|
||||
m = _mm_aesdec_si128(m, K11); \
|
||||
m = _mm_aesdec_si128(m, K12); \
|
||||
m = _mm_aesdec_si128(m, K13); \
|
||||
m = _mm_aesdeclast_si128(m, K14);
|
||||
|
||||
#define SIZE 128
|
||||
#define SIZED(m) m##128
|
||||
#define PRELOAD_ENC PRELOAD_ENC_KEYS128
|
||||
#define DO_ENC_BLOCK DO_ENC_BLOCK128
|
||||
#define PRELOAD_DEC PRELOAD_DEC_KEYS128
|
||||
#define DO_DEC_BLOCK DO_DEC_BLOCK128
|
||||
#include "aes_x86ni_impl.c"
|
||||
|
||||
#undef SIZE
|
||||
#undef SIZED
|
||||
#undef PRELOAD_ENC
|
||||
#undef PRELOAD_DEC
|
||||
#undef DO_ENC_BLOCK
|
||||
#undef DO_DEC_BLOCK
|
||||
|
||||
#define SIZED(m) m##256
|
||||
#define SIZE 256
|
||||
#define PRELOAD_ENC PRELOAD_ENC_KEYS256
|
||||
#define DO_ENC_BLOCK DO_ENC_BLOCK256
|
||||
#define PRELOAD_DEC PRELOAD_DEC_KEYS256
|
||||
#define DO_DEC_BLOCK DO_DEC_BLOCK256
|
||||
#include "aes_x86ni_impl.c"
|
||||
|
||||
#undef SIZE
|
||||
#undef SIZED
|
||||
#undef PRELOAD_ENC
|
||||
#undef PRELOAD_DEC
|
||||
#undef DO_ENC_BLOCK
|
||||
#undef DO_DEC_BLOCK
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
81
cbits/aes/x86ni.h
Normal file
81
cbits/aes/x86ni.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef AES_X86NI_H
|
||||
#define AES_X86NI_H
|
||||
|
||||
#ifdef WITH_AESNI
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
#include <wmmintrin.h>
|
||||
#include <tmmintrin.h>
|
||||
#include <cryptonite_aes.h>
|
||||
#include <aes/block128.h>
|
||||
|
||||
#ifdef IMPL_DEBUG
|
||||
static void block128_sse_print(__m128i m)
|
||||
{
|
||||
block128 b;
|
||||
_mm_storeu_si128((__m128i *) &b.b, m);
|
||||
block128_print(&b);
|
||||
}
|
||||
#endif
|
||||
|
||||
void aes_ni_init(aes_key *key, uint8_t *origkey, uint8_t size);
|
||||
void aes_ni_encrypt_block128(aes_block *out, aes_key *key, aes_block *in);
|
||||
void aes_ni_encrypt_block256(aes_block *out, aes_key *key, aes_block *in);
|
||||
void aes_ni_decrypt_block128(aes_block *out, aes_key *key, aes_block *in);
|
||||
void aes_ni_decrypt_block256(aes_block *out, aes_key *key, aes_block *in);
|
||||
void aes_ni_encrypt_ecb128(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_encrypt_ecb256(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_decrypt_ecb128(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_decrypt_ecb256(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_encrypt_cbc128(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_encrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_decrypt_cbc128(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_decrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_encrypt_ctr128(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length);
|
||||
void aes_ni_encrypt_ctr256(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length);
|
||||
void aes_ni_encrypt_xts128(aes_block *out, aes_key *key1, aes_key *key2,
|
||||
aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks);
|
||||
void aes_ni_encrypt_xts256(aes_block *out, aes_key *key1, aes_key *key2,
|
||||
aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks);
|
||||
|
||||
void aes_ni_gcm_encrypt128(uint8_t *out, aes_gcm *gcm, aes_key *key, uint8_t *in, uint32_t length);
|
||||
void aes_ni_gcm_encrypt256(uint8_t *out, aes_gcm *gcm, aes_key *key, uint8_t *in, uint32_t length);
|
||||
|
||||
void gf_mul_x86ni(block128 *res, block128 *a_, block128 *b_);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
750
cbits/cryptonite_aes.c
Normal file
750
cbits/cryptonite_aes.c
Normal file
@ -0,0 +1,750 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cryptonite_cpu.h>
|
||||
#include <cryptonite_aes.h>
|
||||
#include <cryptonite_bitfn.h>
|
||||
|
||||
#include <aes/generic.h>
|
||||
#include <aes/gf.h>
|
||||
#include <aes/x86ni.h>
|
||||
|
||||
void aes_generic_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);
|
||||
void aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);
|
||||
void aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
|
||||
void aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
|
||||
void aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length);
|
||||
void aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks);
|
||||
void aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks);
|
||||
void aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void aes_generic_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void aes_generic_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
|
||||
|
||||
enum {
|
||||
/* init */
|
||||
INIT_128, INIT_192, INIT_256,
|
||||
/* single block */
|
||||
ENCRYPT_BLOCK_128, ENCRYPT_BLOCK_192, ENCRYPT_BLOCK_256,
|
||||
DECRYPT_BLOCK_128, DECRYPT_BLOCK_192, DECRYPT_BLOCK_256,
|
||||
/* ecb */
|
||||
ENCRYPT_ECB_128, ENCRYPT_ECB_192, ENCRYPT_ECB_256,
|
||||
DECRYPT_ECB_128, DECRYPT_ECB_192, DECRYPT_ECB_256,
|
||||
/* cbc */
|
||||
ENCRYPT_CBC_128, ENCRYPT_CBC_192, ENCRYPT_CBC_256,
|
||||
DECRYPT_CBC_128, DECRYPT_CBC_192, DECRYPT_CBC_256,
|
||||
/* ctr */
|
||||
ENCRYPT_CTR_128, ENCRYPT_CTR_192, ENCRYPT_CTR_256,
|
||||
/* xts */
|
||||
ENCRYPT_XTS_128, ENCRYPT_XTS_192, ENCRYPT_XTS_256,
|
||||
DECRYPT_XTS_128, DECRYPT_XTS_192, DECRYPT_XTS_256,
|
||||
/* gcm */
|
||||
ENCRYPT_GCM_128, ENCRYPT_GCM_192, ENCRYPT_GCM_256,
|
||||
DECRYPT_GCM_128, DECRYPT_GCM_192, DECRYPT_GCM_256,
|
||||
/* ocb */
|
||||
ENCRYPT_OCB_128, ENCRYPT_OCB_192, ENCRYPT_OCB_256,
|
||||
DECRYPT_OCB_128, DECRYPT_OCB_192, DECRYPT_OCB_256,
|
||||
};
|
||||
|
||||
void *branch_table[] = {
|
||||
/* INIT */
|
||||
[INIT_128] = aes_generic_init,
|
||||
[INIT_192] = aes_generic_init,
|
||||
[INIT_256] = aes_generic_init,
|
||||
/* BLOCK */
|
||||
[ENCRYPT_BLOCK_128] = aes_generic_encrypt_block,
|
||||
[ENCRYPT_BLOCK_192] = aes_generic_encrypt_block,
|
||||
[ENCRYPT_BLOCK_256] = aes_generic_encrypt_block,
|
||||
[DECRYPT_BLOCK_128] = aes_generic_decrypt_block,
|
||||
[DECRYPT_BLOCK_192] = aes_generic_decrypt_block,
|
||||
[DECRYPT_BLOCK_256] = aes_generic_decrypt_block,
|
||||
/* ECB */
|
||||
[ENCRYPT_ECB_128] = aes_generic_encrypt_ecb,
|
||||
[ENCRYPT_ECB_192] = aes_generic_encrypt_ecb,
|
||||
[ENCRYPT_ECB_256] = aes_generic_encrypt_ecb,
|
||||
[DECRYPT_ECB_128] = aes_generic_decrypt_ecb,
|
||||
[DECRYPT_ECB_192] = aes_generic_decrypt_ecb,
|
||||
[DECRYPT_ECB_256] = aes_generic_decrypt_ecb,
|
||||
/* CBC */
|
||||
[ENCRYPT_CBC_128] = aes_generic_encrypt_cbc,
|
||||
[ENCRYPT_CBC_192] = aes_generic_encrypt_cbc,
|
||||
[ENCRYPT_CBC_256] = aes_generic_encrypt_cbc,
|
||||
[DECRYPT_CBC_128] = aes_generic_decrypt_cbc,
|
||||
[DECRYPT_CBC_192] = aes_generic_decrypt_cbc,
|
||||
[DECRYPT_CBC_256] = aes_generic_decrypt_cbc,
|
||||
/* CTR */
|
||||
[ENCRYPT_CTR_128] = aes_generic_encrypt_ctr,
|
||||
[ENCRYPT_CTR_192] = aes_generic_encrypt_ctr,
|
||||
[ENCRYPT_CTR_256] = aes_generic_encrypt_ctr,
|
||||
/* XTS */
|
||||
[ENCRYPT_XTS_128] = aes_generic_encrypt_xts,
|
||||
[ENCRYPT_XTS_192] = aes_generic_encrypt_xts,
|
||||
[ENCRYPT_XTS_256] = aes_generic_encrypt_xts,
|
||||
[DECRYPT_XTS_128] = aes_generic_decrypt_xts,
|
||||
[DECRYPT_XTS_192] = aes_generic_decrypt_xts,
|
||||
[DECRYPT_XTS_256] = aes_generic_decrypt_xts,
|
||||
/* GCM */
|
||||
[ENCRYPT_GCM_128] = aes_generic_gcm_encrypt,
|
||||
[ENCRYPT_GCM_192] = aes_generic_gcm_encrypt,
|
||||
[ENCRYPT_GCM_256] = aes_generic_gcm_encrypt,
|
||||
[DECRYPT_GCM_128] = aes_generic_gcm_decrypt,
|
||||
[DECRYPT_GCM_192] = aes_generic_gcm_decrypt,
|
||||
[DECRYPT_GCM_256] = aes_generic_gcm_decrypt,
|
||||
/* OCB */
|
||||
[ENCRYPT_OCB_128] = aes_generic_ocb_encrypt,
|
||||
[ENCRYPT_OCB_192] = aes_generic_ocb_encrypt,
|
||||
[ENCRYPT_OCB_256] = aes_generic_ocb_encrypt,
|
||||
[DECRYPT_OCB_128] = aes_generic_ocb_decrypt,
|
||||
[DECRYPT_OCB_192] = aes_generic_ocb_decrypt,
|
||||
[DECRYPT_OCB_256] = aes_generic_ocb_decrypt,
|
||||
};
|
||||
|
||||
typedef void (*init_f)(aes_key *, uint8_t *, uint8_t);
|
||||
typedef void (*ecb_f)(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);
|
||||
typedef void (*cbc_f)(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
|
||||
typedef void (*ctr_f)(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length);
|
||||
typedef void (*xts_f)(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks);
|
||||
typedef void (*gcm_crypt_f)(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
|
||||
typedef void (*ocb_crypt_f)(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
|
||||
typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input);
|
||||
|
||||
#ifdef WITH_AESNI
|
||||
#define GET_INIT(strength) \
|
||||
((init_f) (branch_table[INIT_128 + strength]))
|
||||
#define GET_ECB_ENCRYPT(strength) \
|
||||
((ecb_f) (branch_table[ENCRYPT_ECB_128 + strength]))
|
||||
#define GET_ECB_DECRYPT(strength) \
|
||||
((ecb_f) (branch_table[DECRYPT_ECB_128 + strength]))
|
||||
#define GET_CBC_ENCRYPT(strength) \
|
||||
((cbc_f) (branch_table[ENCRYPT_CBC_128 + strength]))
|
||||
#define GET_CBC_DECRYPT(strength) \
|
||||
((cbc_f) (branch_table[DECRYPT_CBC_128 + strength]))
|
||||
#define GET_CTR_ENCRYPT(strength) \
|
||||
((ctr_f) (branch_table[ENCRYPT_CTR_128 + strength]))
|
||||
#define GET_XTS_ENCRYPT(strength) \
|
||||
((xts_f) (branch_table[ENCRYPT_XTS_128 + strength]))
|
||||
#define GET_XTS_DECRYPT(strength) \
|
||||
((xts_f) (branch_table[DECRYPT_XTS_128 + strength]))
|
||||
#define GET_GCM_ENCRYPT(strength) \
|
||||
((gcm_crypt_f) (branch_table[ENCRYPT_GCM_128 + strength]))
|
||||
#define GET_GCM_DECRYPT(strength) \
|
||||
((gcm_crypt_f) (branch_table[DECRYPT_GCM_128 + strength]))
|
||||
#define GET_OCB_ENCRYPT(strength) \
|
||||
((ocb_crypt_f) (branch_table[ENCRYPT_OCB_128 + strength]))
|
||||
#define GET_OCB_DECRYPT(strength) \
|
||||
((ocb_crypt_f) (branch_table[DECRYPT_OCB_128 + strength]))
|
||||
#define aes_encrypt_block(o,k,i) \
|
||||
(((block_f) (branch_table[ENCRYPT_BLOCK_128 + k->strength]))(o,k,i))
|
||||
#define aes_decrypt_block(o,k,i) \
|
||||
(((block_f) (branch_table[DECRYPT_BLOCK_128 + k->strength]))(o,k,i))
|
||||
#else
|
||||
#define GET_INIT(strenght) aes_generic_init
|
||||
#define GET_ECB_ENCRYPT(strength) aes_generic_encrypt_ecb
|
||||
#define GET_ECB_DECRYPT(strength) aes_generic_decrypt_ecb
|
||||
#define GET_CBC_ENCRYPT(strength) aes_generic_encrypt_cbc
|
||||
#define GET_CBC_DECRYPT(strength) aes_generic_decrypt_cbc
|
||||
#define GET_CTR_ENCRYPT(strength) aes_generic_encrypt_ctr
|
||||
#define GET_XTS_ENCRYPT(strength) aes_generic_encrypt_xts
|
||||
#define GET_XTS_DECRYPT(strength) aes_generic_decrypt_xts
|
||||
#define GET_GCM_ENCRYPT(strength) aes_generic_gcm_encrypt
|
||||
#define GET_GCM_DECRYPT(strength) aes_generic_gcm_decrypt
|
||||
#define GET_OCB_ENCRYPT(strength) aes_generic_ocb_encrypt
|
||||
#define GET_OCB_DECRYPT(strength) aes_generic_ocb_decrypt
|
||||
#define aes_encrypt_block(o,k,i) aes_generic_encrypt_block(o,k,i)
|
||||
#define aes_decrypt_block(o,k,i) aes_generic_decrypt_block(o,k,i)
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_X86) && defined(WITH_AESNI)
|
||||
static void initialize_table_ni(int aesni, int pclmul)
|
||||
{
|
||||
if (!aesni)
|
||||
return;
|
||||
branch_table[INIT_128] = aes_ni_init;
|
||||
branch_table[INIT_256] = aes_ni_init;
|
||||
|
||||
branch_table[ENCRYPT_BLOCK_128] = aes_ni_encrypt_block128;
|
||||
branch_table[DECRYPT_BLOCK_128] = aes_ni_decrypt_block128;
|
||||
branch_table[ENCRYPT_BLOCK_256] = aes_ni_encrypt_block256;
|
||||
branch_table[DECRYPT_BLOCK_256] = aes_ni_decrypt_block256;
|
||||
/* ECB */
|
||||
branch_table[ENCRYPT_ECB_128] = aes_ni_encrypt_ecb128;
|
||||
branch_table[DECRYPT_ECB_128] = aes_ni_decrypt_ecb128;
|
||||
branch_table[ENCRYPT_ECB_256] = aes_ni_encrypt_ecb256;
|
||||
branch_table[DECRYPT_ECB_256] = aes_ni_decrypt_ecb256;
|
||||
/* CBC */
|
||||
branch_table[ENCRYPT_CBC_128] = aes_ni_encrypt_cbc128;
|
||||
branch_table[DECRYPT_CBC_128] = aes_ni_decrypt_cbc128;
|
||||
branch_table[ENCRYPT_CBC_256] = aes_ni_encrypt_cbc256;
|
||||
branch_table[DECRYPT_CBC_256] = aes_ni_decrypt_cbc256;
|
||||
/* CTR */
|
||||
branch_table[ENCRYPT_CTR_128] = aes_ni_encrypt_ctr128;
|
||||
branch_table[ENCRYPT_CTR_256] = aes_ni_encrypt_ctr256;
|
||||
/* XTS */
|
||||
branch_table[ENCRYPT_XTS_128] = aes_ni_encrypt_xts128;
|
||||
branch_table[ENCRYPT_XTS_256] = aes_ni_encrypt_xts256;
|
||||
/* GCM */
|
||||
branch_table[ENCRYPT_GCM_128] = aes_ni_gcm_encrypt128;
|
||||
branch_table[ENCRYPT_GCM_256] = aes_ni_gcm_encrypt256;
|
||||
/* OCB */
|
||||
/*
|
||||
branch_table[ENCRYPT_OCB_128] = aes_ni_ocb_encrypt128;
|
||||
branch_table[ENCRYPT_OCB_256] = aes_ni_ocb_encrypt256;
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
void aes_initkey(aes_key *key, uint8_t *origkey, uint8_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 16: key->nbr = 10; key->strength = 0; break;
|
||||
case 24: key->nbr = 12; key->strength = 1; break;
|
||||
case 32: key->nbr = 14; key->strength = 2; break;
|
||||
}
|
||||
#if defined(ARCH_X86) && defined(WITH_AESNI)
|
||||
initialize_hw(initialize_table_ni);
|
||||
#endif
|
||||
init_f _init = GET_INIT(key->strength);
|
||||
_init(key, origkey, size);
|
||||
}
|
||||
|
||||
void aes_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
ecb_f e = GET_ECB_ENCRYPT(key->strength);
|
||||
e(output, key, input, nb_blocks);
|
||||
}
|
||||
|
||||
void aes_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
ecb_f d = GET_ECB_DECRYPT(key->strength);
|
||||
d(output, key, input, nb_blocks);
|
||||
}
|
||||
|
||||
void aes_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
cbc_f e = GET_CBC_ENCRYPT(key->strength);
|
||||
e(output, key, iv, input, nb_blocks);
|
||||
}
|
||||
|
||||
void aes_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
cbc_f d = GET_CBC_DECRYPT(key->strength);
|
||||
d(output, key, iv, input, nb_blocks);
|
||||
}
|
||||
|
||||
void aes_gen_ctr(aes_block *output, aes_key *key, const aes_block *iv, uint32_t nb_blocks)
|
||||
{
|
||||
aes_block block;
|
||||
|
||||
/* preload IV in block */
|
||||
block128_copy(&block, iv);
|
||||
|
||||
for ( ; nb_blocks-- > 0; output++, block128_inc_be(&block)) {
|
||||
aes_encrypt_block(output, key, &block);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_gen_ctr_cont(aes_block *output, aes_key *key, aes_block *iv, uint32_t nb_blocks)
|
||||
{
|
||||
aes_block block;
|
||||
|
||||
/* preload IV in block */
|
||||
block128_copy(&block, iv);
|
||||
|
||||
for ( ; nb_blocks-- > 0; output++, block128_inc_be(&block)) {
|
||||
aes_encrypt_block(output, key, &block);
|
||||
}
|
||||
|
||||
/* copy back the IV */
|
||||
block128_copy(iv, &block);
|
||||
}
|
||||
|
||||
void aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len)
|
||||
{
|
||||
ctr_f e = GET_CTR_ENCRYPT(key->strength);
|
||||
e(output, key, iv, input, len);
|
||||
}
|
||||
|
||||
void aes_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
xts_f e = GET_XTS_ENCRYPT(k1->strength);
|
||||
e(output, k1, k2, dataunit, spoint, input, nb_blocks);
|
||||
}
|
||||
|
||||
void aes_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
aes_generic_decrypt_xts(output, k1, k2, dataunit, spoint, input, nb_blocks);
|
||||
}
|
||||
|
||||
void aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
gcm_crypt_f e = GET_GCM_ENCRYPT(key->strength);
|
||||
e(output, gcm, key, input, length);
|
||||
}
|
||||
|
||||
void aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
gcm_crypt_f d = GET_GCM_DECRYPT(key->strength);
|
||||
d(output, gcm, key, input, length);
|
||||
}
|
||||
|
||||
void aes_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
ocb_crypt_f e = GET_OCB_ENCRYPT(key->strength);
|
||||
e(output, ocb, key, input, length);
|
||||
}
|
||||
|
||||
void aes_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
ocb_crypt_f d = GET_OCB_DECRYPT(key->strength);
|
||||
d(output, ocb, key, input, length);
|
||||
}
|
||||
|
||||
static void gcm_ghash_add(aes_gcm *gcm, block128 *b)
|
||||
{
|
||||
block128_xor(&gcm->tag, b);
|
||||
gf_mul(&gcm->tag, &gcm->h);
|
||||
}
|
||||
|
||||
void aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len)
|
||||
{
|
||||
gcm->length_aad = 0;
|
||||
gcm->length_input = 0;
|
||||
|
||||
block128_zero(&gcm->h);
|
||||
block128_zero(&gcm->tag);
|
||||
block128_zero(&gcm->iv);
|
||||
|
||||
/* prepare H : encrypt_K(0^128) */
|
||||
aes_encrypt_block(&gcm->h, key, &gcm->h);
|
||||
|
||||
if (len == 12) {
|
||||
block128_copy_bytes(&gcm->iv, iv, 12);
|
||||
gcm->iv.b[15] = 0x01;
|
||||
} else {
|
||||
uint32_t origlen = len << 3;
|
||||
int i;
|
||||
for (; len >= 16; len -= 16, iv += 16) {
|
||||
block128_xor(&gcm->iv, (block128 *) iv);
|
||||
gf_mul(&gcm->iv, &gcm->h);
|
||||
}
|
||||
if (len > 0) {
|
||||
block128_xor_bytes(&gcm->iv, iv, len);
|
||||
gf_mul(&gcm->iv, &gcm->h);
|
||||
}
|
||||
for (i = 15; origlen; --i, origlen >>= 8)
|
||||
gcm->iv.b[i] ^= (uint8_t) origlen;
|
||||
gf_mul(&gcm->iv, &gcm->h);
|
||||
}
|
||||
|
||||
block128_copy(&gcm->civ, &gcm->iv);
|
||||
}
|
||||
|
||||
void aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length)
|
||||
{
|
||||
gcm->length_aad += length;
|
||||
for (; length >= 16; input += 16, length -= 16) {
|
||||
gcm_ghash_add(gcm, (block128 *) input);
|
||||
}
|
||||
if (length > 0) {
|
||||
aes_block tmp;
|
||||
block128_zero(&tmp);
|
||||
block128_copy_bytes(&tmp, input, length);
|
||||
gcm_ghash_add(gcm, &tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key)
|
||||
{
|
||||
aes_block lblock;
|
||||
int i;
|
||||
|
||||
/* tag = (tag-1 xor (lenbits(a) | lenbits(c)) ) . H */
|
||||
lblock.q[0] = cpu_to_be64(gcm->length_aad << 3);
|
||||
lblock.q[1] = cpu_to_be64(gcm->length_input << 3);
|
||||
gcm_ghash_add(gcm, &lblock);
|
||||
|
||||
aes_encrypt_block(&lblock, key, &gcm->iv);
|
||||
block128_xor(&gcm->tag, &lblock);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
tag[i] = gcm->tag.b[i];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ocb_block_double(block128 *d, block128 *s)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t tmp = s->b[0];
|
||||
|
||||
for (i=0; i<15; i++)
|
||||
d->b[i] = (s->b[i] << 1) | (s->b[i+1] >> 7);
|
||||
d->b[15] = (s->b[15] << 1) ^ ((tmp >> 7) * 0x87);
|
||||
}
|
||||
|
||||
static void ocb_get_L_i(block128 *l, block128 *lis, unsigned int i)
|
||||
{
|
||||
#define L_CACHED 4
|
||||
i = bitfn_ntz(i);
|
||||
if (i < L_CACHED) {
|
||||
block128_copy(l, &lis[i]);
|
||||
} else {
|
||||
i -= (L_CACHED - 1);
|
||||
block128_copy(l, &lis[L_CACHED - 1]);
|
||||
while (i--) {
|
||||
ocb_block_double(l, l);
|
||||
}
|
||||
}
|
||||
#undef L_CACHED
|
||||
}
|
||||
|
||||
void aes_ocb_init(aes_ocb *ocb, aes_key *key, uint8_t *iv, uint32_t len)
|
||||
{
|
||||
block128 tmp, nonce, ktop;
|
||||
unsigned char stretch[24];
|
||||
unsigned bottom, byteshift, bitshift, i;
|
||||
|
||||
/* we don't accept more than 15 bytes, any bytes higher will be ignored. */
|
||||
if (len > 15) {
|
||||
len = 15;
|
||||
}
|
||||
|
||||
/* create L*, and L$,L0,L1,L2,L3 */
|
||||
block128_zero(&tmp);
|
||||
aes_encrypt_block(&ocb->lstar, key, &tmp);
|
||||
|
||||
ocb_block_double(&ocb->ldollar, &ocb->lstar);
|
||||
ocb_block_double(&ocb->li[0], &ocb->ldollar);
|
||||
ocb_block_double(&ocb->li[1], &ocb->li[0]);
|
||||
ocb_block_double(&ocb->li[2], &ocb->li[1]);
|
||||
ocb_block_double(&ocb->li[3], &ocb->li[2]);
|
||||
|
||||
/* create strech from the nonce */
|
||||
block128_zero(&nonce);
|
||||
memcpy(nonce.b + 4, iv, 12);
|
||||
nonce.b[0] = (unsigned char)(((16 * 8) % 128) << 1);
|
||||
nonce.b[16-12-1] |= 0x01;
|
||||
bottom = nonce.b[15] & 0x3F;
|
||||
nonce.b[15] &= 0xC0;
|
||||
aes_encrypt_block(&ktop, key, &nonce);
|
||||
memcpy(stretch, ktop.b, 16);
|
||||
|
||||
memcpy(tmp.b, ktop.b + 1, 8);
|
||||
block128_xor(&tmp, &ktop);
|
||||
memcpy(stretch + 16, tmp.b, 8);
|
||||
|
||||
/* initialize the encryption offset from stretch */
|
||||
byteshift = bottom / 8;
|
||||
bitshift = bottom % 8;
|
||||
if (bitshift != 0)
|
||||
for (i = 0; i < 16; i++)
|
||||
ocb->offset_enc.b[i] = (stretch[i+byteshift] << bitshift)
|
||||
| (stretch[i+byteshift+1] >> (8-bitshift));
|
||||
else
|
||||
for (i = 0; i < 16; i++)
|
||||
ocb->offset_enc.b[i] = stretch[i+byteshift];
|
||||
/* initialize checksum for aad and encryption, and the aad offset */
|
||||
block128_zero(&ocb->sum_aad);
|
||||
block128_zero(&ocb->sum_enc);
|
||||
block128_zero(&ocb->offset_aad);
|
||||
}
|
||||
|
||||
void aes_ocb_aad(aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
block128 tmp;
|
||||
unsigned int i;
|
||||
|
||||
for (i=1; i<= length/16; i++, input=input+16) {
|
||||
ocb_get_L_i(&tmp, ocb->li, i);
|
||||
block128_xor(&ocb->offset_aad, &tmp);
|
||||
|
||||
block128_vxor(&tmp, &ocb->offset_aad, (block128 *) input);
|
||||
aes_encrypt_block(&tmp, key, &tmp);
|
||||
block128_xor(&ocb->sum_aad, &tmp);
|
||||
}
|
||||
|
||||
length = length % 16; /* Bytes in final block */
|
||||
if (length > 0) {
|
||||
block128_xor(&ocb->offset_aad, &ocb->lstar);
|
||||
block128_zero(&tmp);
|
||||
block128_copy_bytes(&tmp, input, length);
|
||||
tmp.b[length] = 0x80;
|
||||
block128_xor(&tmp, &ocb->offset_aad);
|
||||
aes_encrypt_block(&tmp, key, &tmp);
|
||||
block128_xor(&ocb->sum_aad, &tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_ocb_finish(uint8_t *tag, aes_ocb *ocb, aes_key *key)
|
||||
{
|
||||
block128 tmp;
|
||||
|
||||
block128_vxor(&tmp, &ocb->sum_enc, &ocb->offset_enc);
|
||||
block128_xor(&tmp, &ocb->ldollar);
|
||||
aes_encrypt_block((block128 *) tag, key, &tmp);
|
||||
block128_xor((block128 *) tag, &ocb->sum_aad);
|
||||
}
|
||||
|
||||
void aes_generic_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
for ( ; nb_blocks-- > 0; input++, output++) {
|
||||
aes_generic_encrypt_block(output, key, input);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
for ( ; nb_blocks-- > 0; input++, output++) {
|
||||
aes_generic_decrypt_block(output, key, input);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
aes_block block;
|
||||
|
||||
/* preload IV in block */
|
||||
block128_copy(&block, iv);
|
||||
for ( ; nb_blocks-- > 0; input++, output++) {
|
||||
block128_xor(&block, (block128 *) input);
|
||||
aes_generic_encrypt_block(&block, key, &block);
|
||||
block128_copy((block128 *) output, &block);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *ivini, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
aes_block block, blocko;
|
||||
aes_block iv;
|
||||
|
||||
/* preload IV in block */
|
||||
block128_copy(&iv, ivini);
|
||||
for ( ; nb_blocks-- > 0; input++, output++) {
|
||||
block128_copy(&block, (block128 *) input);
|
||||
aes_generic_decrypt_block(&blocko, key, &block);
|
||||
block128_vxor((block128 *) output, &blocko, &iv);
|
||||
block128_copy(&iv, &block);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len)
|
||||
{
|
||||
aes_block block, o;
|
||||
uint32_t nb_blocks = len / 16;
|
||||
int i;
|
||||
|
||||
/* preload IV in block */
|
||||
block128_copy(&block, iv);
|
||||
|
||||
for ( ; nb_blocks-- > 0; block128_inc_be(&block), output += 16, input += 16) {
|
||||
aes_encrypt_block(&o, key, &block);
|
||||
block128_vxor((block128 *) output, &o, (block128 *) input);
|
||||
}
|
||||
|
||||
if ((len % 16) != 0) {
|
||||
aes_encrypt_block(&o, key, &block);
|
||||
for (i = 0; i < (len % 16); i++) {
|
||||
*output = ((uint8_t *) &o)[i] ^ *input;
|
||||
output++;
|
||||
input++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
aes_block block, tweak;
|
||||
|
||||
/* load IV and encrypt it using k2 as the tweak */
|
||||
block128_copy(&tweak, dataunit);
|
||||
aes_encrypt_block(&tweak, k2, &tweak);
|
||||
|
||||
/* TO OPTIMISE: this is really inefficient way to do that */
|
||||
while (spoint-- > 0)
|
||||
gf_mulx(&tweak);
|
||||
|
||||
for ( ; nb_blocks-- > 0; input++, output++, gf_mulx(&tweak)) {
|
||||
block128_vxor(&block, input, &tweak);
|
||||
aes_encrypt_block(&block, k1, &block);
|
||||
block128_vxor(output, &block, &tweak);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks)
|
||||
{
|
||||
aes_block block, tweak;
|
||||
|
||||
/* load IV and encrypt it using k2 as the tweak */
|
||||
block128_copy(&tweak, dataunit);
|
||||
aes_encrypt_block(&tweak, k2, &tweak);
|
||||
|
||||
/* TO OPTIMISE: this is really inefficient way to do that */
|
||||
while (spoint-- > 0)
|
||||
gf_mulx(&tweak);
|
||||
|
||||
for ( ; nb_blocks-- > 0; input++, output++, gf_mulx(&tweak)) {
|
||||
block128_vxor(&block, input, &tweak);
|
||||
aes_decrypt_block(&block, k1, &block);
|
||||
block128_vxor(output, &block, &tweak);
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
aes_block out;
|
||||
|
||||
gcm->length_input += length;
|
||||
for (; length >= 16; input += 16, output += 16, length -= 16) {
|
||||
block128_inc_be(&gcm->civ);
|
||||
|
||||
aes_encrypt_block(&out, key, &gcm->civ);
|
||||
block128_xor(&out, (block128 *) input);
|
||||
gcm_ghash_add(gcm, &out);
|
||||
block128_copy((block128 *) output, &out);
|
||||
}
|
||||
if (length > 0) {
|
||||
aes_block tmp;
|
||||
int i;
|
||||
|
||||
block128_inc_be(&gcm->civ);
|
||||
/* create e(civ) in out */
|
||||
aes_encrypt_block(&out, key, &gcm->civ);
|
||||
/* initialize a tmp as input and xor it to e(civ) */
|
||||
block128_zero(&tmp);
|
||||
block128_copy_bytes(&tmp, input, length);
|
||||
block128_xor_bytes(&tmp, out.b, length);
|
||||
|
||||
gcm_ghash_add(gcm, &tmp);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
output[i] = tmp.b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
aes_block out;
|
||||
|
||||
gcm->length_input += length;
|
||||
for (; length >= 16; input += 16, output += 16, length -= 16) {
|
||||
block128_inc_be(&gcm->civ);
|
||||
|
||||
aes_encrypt_block(&out, key, &gcm->civ);
|
||||
gcm_ghash_add(gcm, (block128 *) input);
|
||||
block128_xor(&out, (block128 *) input);
|
||||
block128_copy((block128 *) output, &out);
|
||||
}
|
||||
if (length > 0) {
|
||||
aes_block tmp;
|
||||
int i;
|
||||
|
||||
block128_inc_be(&gcm->civ);
|
||||
|
||||
block128_zero(&tmp);
|
||||
block128_copy_bytes(&tmp, input, length);
|
||||
gcm_ghash_add(gcm, &tmp);
|
||||
|
||||
aes_encrypt_block(&out, key, &gcm->civ);
|
||||
block128_xor_bytes(&tmp, out.b, length);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
output[i] = tmp.b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ocb_generic_crypt(uint8_t *output, aes_ocb *ocb, aes_key *key,
|
||||
uint8_t *input, uint32_t length, int encrypt)
|
||||
{
|
||||
block128 tmp, pad;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i <= length/16; i++, input += 16, output += 16) {
|
||||
/* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
|
||||
ocb_get_L_i(&tmp, ocb->li, i);
|
||||
block128_xor(&ocb->offset_enc, &tmp);
|
||||
|
||||
block128_vxor(&tmp, &ocb->offset_enc, (block128 *) input);
|
||||
if (encrypt) {
|
||||
aes_encrypt_block(&tmp, key, &tmp);
|
||||
block128_vxor((block128 *) output, &ocb->offset_enc, &tmp);
|
||||
block128_xor(&ocb->sum_enc, (block128 *) input);
|
||||
} else {
|
||||
aes_decrypt_block(&tmp, key, &tmp);
|
||||
block128_vxor((block128 *) output, &ocb->offset_enc, &tmp);
|
||||
block128_xor(&ocb->sum_enc, (block128 *) output);
|
||||
}
|
||||
}
|
||||
|
||||
/* process the last partial block if any */
|
||||
length = length % 16;
|
||||
if (length > 0) {
|
||||
block128_xor(&ocb->offset_enc, &ocb->lstar);
|
||||
aes_encrypt_block(&pad, key, &ocb->offset_enc);
|
||||
|
||||
if (encrypt) {
|
||||
block128_zero(&tmp);
|
||||
block128_copy_bytes(&tmp, input, length);
|
||||
tmp.b[length] = 0x80;
|
||||
block128_xor(&ocb->sum_enc, &tmp);
|
||||
block128_xor(&pad, &tmp);
|
||||
memcpy(output, pad.b, length);
|
||||
output += length;
|
||||
} else {
|
||||
block128_copy(&tmp, &pad);
|
||||
block128_copy_bytes(&tmp, input, length);
|
||||
block128_xor(&tmp, &pad);
|
||||
tmp.b[length] = 0x80;
|
||||
memcpy(output, tmp.b, length);
|
||||
block128_xor(&ocb->sum_enc, &tmp);
|
||||
input += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aes_generic_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
ocb_generic_crypt(output, ocb, key, input, length, 1);
|
||||
}
|
||||
|
||||
void aes_generic_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
|
||||
{
|
||||
ocb_generic_crypt(output, ocb, key, input, length, 0);
|
||||
}
|
||||
100
cbits/cryptonite_aes.h
Normal file
100
cbits/cryptonite_aes.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Vincent Hanquez <tab@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* AES implementation
|
||||
*/
|
||||
#ifndef CRYPTONITE_AES_H
|
||||
#define CRYPTONITE_AES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "aes/block128.h"
|
||||
|
||||
typedef block128 aes_block;
|
||||
|
||||
/* size = 456 */
|
||||
typedef struct {
|
||||
uint8_t nbr; /* number of rounds: 10 (128), 12 (192), 14 (256) */
|
||||
uint8_t strength; /* 128 = 0, 192 = 1, 256 = 2 */
|
||||
uint8_t _padding[6];
|
||||
uint8_t data[16*14*2];
|
||||
} aes_key;
|
||||
|
||||
/* size = 4*16+2*8= 80 */
|
||||
typedef struct {
|
||||
aes_block tag;
|
||||
aes_block h;
|
||||
aes_block iv;
|
||||
aes_block civ;
|
||||
uint64_t length_aad;
|
||||
uint64_t length_input;
|
||||
} aes_gcm;
|
||||
|
||||
typedef struct {
|
||||
block128 offset_aad;
|
||||
block128 offset_enc;
|
||||
block128 sum_aad;
|
||||
block128 sum_enc;
|
||||
block128 lstar;
|
||||
block128 ldollar;
|
||||
block128 li[4];
|
||||
} aes_ocb;
|
||||
|
||||
/* in bytes: either 16,24,32 */
|
||||
void cryptonite_aes_initkey(aes_key *ctx, uint8_t *key, uint8_t size);
|
||||
|
||||
void cryptonite_aes_encrypt(aes_block *output, aes_key *key, aes_block *input);
|
||||
void cryptonite_aes_decrypt(aes_block *output, aes_key *key, aes_block *input);
|
||||
|
||||
void cryptonite_aes_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);
|
||||
void cryptonite_aes_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);
|
||||
|
||||
void cryptonite_aes_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
|
||||
void cryptonite_aes_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
|
||||
|
||||
void cryptonite_aes_gen_ctr(aes_block *output, aes_key *key, const aes_block *iv, uint32_t nb_blocks);
|
||||
void cryptonite_aes_gen_ctr_cont(aes_block *output, aes_key *key, aes_block *iv, uint32_t nb_blocks);
|
||||
|
||||
void cryptonite_aes_encrypt_xts(aes_block *output, aes_key *key, aes_key *key2, aes_block *sector,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks);
|
||||
void cryptonite_aes_decrypt_xts(aes_block *output, aes_key *key, aes_key *key2, aes_block *sector,
|
||||
uint32_t spoint, aes_block *input, uint32_t nb_blocks);
|
||||
|
||||
void cryptonite_aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len);
|
||||
void cryptonite_aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length);
|
||||
void cryptonite_aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void cryptonite_aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void cryptonite_aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key);
|
||||
|
||||
void cryptonite_aes_ocb_init(aes_ocb *ocb, aes_key *key, uint8_t *iv, uint32_t len);
|
||||
void cryptonite_aes_ocb_aad(aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void cryptonite_aes_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void cryptonite_aes_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
|
||||
void cryptonite_aes_ocb_finish(uint8_t *tag, aes_ocb *ocb, aes_key *key);
|
||||
|
||||
#endif
|
||||
@ -165,6 +165,12 @@ static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define bitfn_ntz(n) __builtin_ctz(n)
|
||||
#else
|
||||
#error "define ntz for your platform"
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
|
||||
75
cbits/cryptonite_cpu.c
Normal file
75
cbits/cryptonite_cpu.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Vincent Hanquez <tab@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "cryptonite_cpu.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef ARCH_X86
|
||||
static void cpuid(uint32_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
*eax = info;
|
||||
asm volatile
|
||||
(
|
||||
#ifdef __x86_64__
|
||||
"mov %%rbx, %%rdi;"
|
||||
#else
|
||||
"mov %%ebx, %%edi;"
|
||||
#endif
|
||||
"cpuid;"
|
||||
"mov %%ebx, %%esi;"
|
||||
#ifdef __x86_64__
|
||||
"mov %%rdi, %%rbx;"
|
||||
#else
|
||||
"mov %%edi, %%ebx;"
|
||||
#endif
|
||||
:"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
|
||||
: :"edi");
|
||||
}
|
||||
|
||||
#ifdef USE_AESNI
|
||||
void initialize_hw(void (*init_table)(int, int))
|
||||
{
|
||||
static int inited = 0;
|
||||
if (inited == 0) {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
int aesni, pclmul;
|
||||
|
||||
inited = 1;
|
||||
cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
aesni = (ecx & 0x02000000);
|
||||
pclmul = (ecx & 0x00000001);
|
||||
init_table(aesni, pclmul);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define initialize_hw(init_table) (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
45
cbits/cryptonite_cpu.h
Normal file
45
cbits/cryptonite_cpu.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Vincent Hanquez <tab@snarc.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define ARCH_X86
|
||||
#define USE_AESNI
|
||||
#endif
|
||||
|
||||
#ifdef USE_AESNI
|
||||
void initialize_hw(void (*init_table)(int, int));
|
||||
#else
|
||||
#define initialize_hw(init_table) (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -20,6 +20,10 @@ source-repository head
|
||||
type: git
|
||||
location: https://github.com/vincenthz/cryptonite
|
||||
|
||||
Flag support_aesni
|
||||
Description: allow compilation with AESNI on system and architecture that supports it
|
||||
Default: True
|
||||
|
||||
Library
|
||||
Exposed-modules: Crypto.Cipher.ChaCha
|
||||
Crypto.Cipher.Salsa
|
||||
@ -64,6 +68,10 @@ Library
|
||||
C-sources: cbits/cryptonite_chacha.c
|
||||
, cbits/cryptonite_salsa.c
|
||||
, cbits/cryptonite_rc4.c
|
||||
, cbits/cryptonite_cpu.c
|
||||
, cbits/aes/generic.c
|
||||
, cbits/aes/gf.c
|
||||
, cbits/cryptonite_aes.c
|
||||
, cbits/cryptonite_poly1305.c
|
||||
, cbits/cryptonite_sha1.c
|
||||
, cbits/cryptonite_sha256.c
|
||||
@ -79,14 +87,19 @@ Library
|
||||
, cbits/cryptonite_tiger.c
|
||||
, cbits/cryptonite_whirlpool.c
|
||||
, cbits/cryptonite_scrypt.c
|
||||
include-dirs: cbits
|
||||
if (arch(i386) || arch(x86_64))
|
||||
CPP-options: -DARCH_IS_LITTLE_ENDIAN
|
||||
|
||||
if arch(x86_64)
|
||||
cpp-options: -DSUPPORT_RDRAND
|
||||
CPP-options: -DSUPPORT_RDRAND
|
||||
Other-modules: Crypto.Random.Entropy.RDRand
|
||||
c-sources: cbits/cryptonite_rdrand.c
|
||||
|
||||
if flag(support_aesni) && (os(linux) || os(freebsd) || os(osx)) && (arch(i386) || arch(x86_64))
|
||||
CC-options: -mssse3 -maes -mpclmul -DWITH_AESNI
|
||||
C-sources: cbits/aes/x86ni.c
|
||||
|
||||
if os(windows)
|
||||
cpp-options: -DWINDOWS
|
||||
Build-Depends: Win32
|
||||
|
||||
Loading…
Reference in New Issue
Block a user