oxen-core/src/crypto/oaes_lib_expand.c
Jason Rhinelander 13409ad00e
run clang format
2023-04-13 17:15:12 -03:00

377 lines
7.7 KiB
C

/*
* ---------------------------------------------------------------------------
* OpenAES License
* ---------------------------------------------------------------------------
* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 "oaes_lib_expand.h"
#include <assert.h>
#include <stddef.h>
#include <string.h>
#define OAES_RKEY_LEN 4
#define OAES_COL_LEN 4
#define OAES_ROUND_BASE 7
static uint8_t oaes_gf_8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
static uint8_t oaes_sub_byte_value[16][16] = {
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c,
// d, e, f,
/*0*/ {0x63,
0x7c,
0x77,
0x7b,
0xf2,
0x6b,
0x6f,
0xc5,
0x30,
0x01,
0x67,
0x2b,
0xfe,
0xd7,
0xab,
0x76},
/*1*/
{0xca,
0x82,
0xc9,
0x7d,
0xfa,
0x59,
0x47,
0xf0,
0xad,
0xd4,
0xa2,
0xaf,
0x9c,
0xa4,
0x72,
0xc0},
/*2*/
{0xb7,
0xfd,
0x93,
0x26,
0x36,
0x3f,
0xf7,
0xcc,
0x34,
0xa5,
0xe5,
0xf1,
0x71,
0xd8,
0x31,
0x15},
/*3*/
{0x04,
0xc7,
0x23,
0xc3,
0x18,
0x96,
0x05,
0x9a,
0x07,
0x12,
0x80,
0xe2,
0xeb,
0x27,
0xb2,
0x75},
/*4*/
{0x09,
0x83,
0x2c,
0x1a,
0x1b,
0x6e,
0x5a,
0xa0,
0x52,
0x3b,
0xd6,
0xb3,
0x29,
0xe3,
0x2f,
0x84},
/*5*/
{0x53,
0xd1,
0x00,
0xed,
0x20,
0xfc,
0xb1,
0x5b,
0x6a,
0xcb,
0xbe,
0x39,
0x4a,
0x4c,
0x58,
0xcf},
/*6*/
{0xd0,
0xef,
0xaa,
0xfb,
0x43,
0x4d,
0x33,
0x85,
0x45,
0xf9,
0x02,
0x7f,
0x50,
0x3c,
0x9f,
0xa8},
/*7*/
{0x51,
0xa3,
0x40,
0x8f,
0x92,
0x9d,
0x38,
0xf5,
0xbc,
0xb6,
0xda,
0x21,
0x10,
0xff,
0xf3,
0xd2},
/*8*/
{0xcd,
0x0c,
0x13,
0xec,
0x5f,
0x97,
0x44,
0x17,
0xc4,
0xa7,
0x7e,
0x3d,
0x64,
0x5d,
0x19,
0x73},
/*9*/
{0x60,
0x81,
0x4f,
0xdc,
0x22,
0x2a,
0x90,
0x88,
0x46,
0xee,
0xb8,
0x14,
0xde,
0x5e,
0x0b,
0xdb},
/*a*/
{0xe0,
0x32,
0x3a,
0x0a,
0x49,
0x06,
0x24,
0x5c,
0xc2,
0xd3,
0xac,
0x62,
0x91,
0x95,
0xe4,
0x79},
/*b*/
{0xe7,
0xc8,
0x37,
0x6d,
0x8d,
0xd5,
0x4e,
0xa9,
0x6c,
0x56,
0xf4,
0xea,
0x65,
0x7a,
0xae,
0x08},
/*c*/
{0xba,
0x78,
0x25,
0x2e,
0x1c,
0xa6,
0xb4,
0xc6,
0xe8,
0xdd,
0x74,
0x1f,
0x4b,
0xbd,
0x8b,
0x8a},
/*d*/
{0x70,
0x3e,
0xb5,
0x66,
0x48,
0x03,
0xf6,
0x0e,
0x61,
0x35,
0x57,
0xb9,
0x86,
0xc1,
0x1d,
0x9e},
/*e*/
{0xe1,
0xf8,
0x98,
0x11,
0x69,
0xd9,
0x8e,
0x94,
0x9b,
0x1e,
0x87,
0xe9,
0xce,
0x55,
0x28,
0xdf},
/*f*/
{0x8c,
0xa1,
0x89,
0x0d,
0xbf,
0xe6,
0x42,
0x68,
0x41,
0x99,
0x2d,
0x0f,
0xb0,
0x54,
0xbb,
0x16},
};
static void oaes_sub_byte(uint8_t* byte) {
size_t _x, _y;
if (NULL == byte)
return;
_x = _y = *byte;
_x &= 0x0f;
_y &= 0xf0;
_y >>= 4;
*byte = oaes_sub_byte_value[_y][_x];
}
static void oaes_word_rot_left(uint8_t word[OAES_COL_LEN]) {
uint8_t _temp[OAES_COL_LEN];
if (NULL == word)
return;
memcpy(_temp, word + 1, OAES_COL_LEN - 1);
_temp[OAES_COL_LEN - 1] = word[0];
memcpy(word, _temp, OAES_COL_LEN);
}
void oaes_expand_key_256(const uint8_t* data, uint8_t* exp_data) {
size_t _i, _j;
const size_t key_base = 32 / OAES_RKEY_LEN;
const size_t num_keys = key_base + OAES_ROUND_BASE;
assert(num_keys * OAES_RKEY_LEN * OAES_COL_LEN == 240);
// the first key->data_len are a direct copy
memcpy(exp_data, data, 32);
// apply ExpandKey algorithm for remainder
for (_i = key_base; _i < num_keys * OAES_RKEY_LEN; _i++) {
uint8_t _temp[OAES_COL_LEN];
memcpy(_temp, exp_data + (_i - 1) * OAES_RKEY_LEN, OAES_COL_LEN);
// transform key column
if (0 == _i % key_base) {
oaes_word_rot_left(_temp);
for (_j = 0; _j < OAES_COL_LEN; _j++)
oaes_sub_byte(_temp + _j);
_temp[0] = _temp[0] ^ oaes_gf_8[_i / key_base - 1];
} else if (key_base > 6 && 4 == _i % key_base) {
for (_j = 0; _j < OAES_COL_LEN; _j++)
oaes_sub_byte(_temp + _j);
}
for (_j = 0; _j < OAES_COL_LEN; _j++) {
exp_data[_i * OAES_RKEY_LEN + _j] =
exp_data[(_i - key_base) * OAES_RKEY_LEN + _j] ^ _temp[_j];
}
}
}