Path: blob/main/contrib/bearssl/src/symcipher/aes_small_enc.c
39482 views
/*1* Copyright (c) 2016 Thomas Pornin <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining4* a copy of this software and associated documentation files (the5* "Software"), to deal in the Software without restriction, including6* without limitation the rights to use, copy, modify, merge, publish,7* distribute, sublicense, and/or sell copies of the Software, and to8* permit persons to whom the Software is furnished to do so, subject to9* the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#include "inner.h"2526#define S br_aes_S2728static void29add_round_key(unsigned *state, const uint32_t *skeys)30{31int i;3233for (i = 0; i < 16; i += 4) {34uint32_t k;3536k = *skeys ++;37state[i + 0] ^= (unsigned)(k >> 24);38state[i + 1] ^= (unsigned)(k >> 16) & 0xFF;39state[i + 2] ^= (unsigned)(k >> 8) & 0xFF;40state[i + 3] ^= (unsigned)k & 0xFF;41}42}4344static void45sub_bytes(unsigned *state)46{47int i;4849for (i = 0; i < 16; i ++) {50state[i] = S[state[i]];51}52}5354static void55shift_rows(unsigned *state)56{57unsigned tmp;5859tmp = state[1];60state[1] = state[5];61state[5] = state[9];62state[9] = state[13];63state[13] = tmp;6465tmp = state[2];66state[2] = state[10];67state[10] = tmp;68tmp = state[6];69state[6] = state[14];70state[14] = tmp;7172tmp = state[15];73state[15] = state[11];74state[11] = state[7];75state[7] = state[3];76state[3] = tmp;77}7879static void80mix_columns(unsigned *state)81{82int i;8384for (i = 0; i < 16; i += 4) {85unsigned s0, s1, s2, s3;86unsigned t0, t1, t2, t3;8788s0 = state[i + 0];89s1 = state[i + 1];90s2 = state[i + 2];91s3 = state[i + 3];92t0 = (s0 << 1) ^ s1 ^ (s1 << 1) ^ s2 ^ s3;93t1 = s0 ^ (s1 << 1) ^ s2 ^ (s2 << 1) ^ s3;94t2 = s0 ^ s1 ^ (s2 << 1) ^ s3 ^ (s3 << 1);95t3 = s0 ^ (s0 << 1) ^ s1 ^ s2 ^ (s3 << 1);96state[i + 0] = t0 ^ ((unsigned)(-(int)(t0 >> 8)) & 0x11B);97state[i + 1] = t1 ^ ((unsigned)(-(int)(t1 >> 8)) & 0x11B);98state[i + 2] = t2 ^ ((unsigned)(-(int)(t2 >> 8)) & 0x11B);99state[i + 3] = t3 ^ ((unsigned)(-(int)(t3 >> 8)) & 0x11B);100}101}102103/* see inner.h */104void105br_aes_small_encrypt(unsigned num_rounds, const uint32_t *skey, void *data)106{107unsigned char *buf;108unsigned state[16];109unsigned u;110111buf = data;112for (u = 0; u < 16; u ++) {113state[u] = buf[u];114}115add_round_key(state, skey);116for (u = 1; u < num_rounds; u ++) {117sub_bytes(state);118shift_rows(state);119mix_columns(state);120add_round_key(state, skey + (u << 2));121}122sub_bytes(state);123shift_rows(state);124add_round_key(state, skey + (num_rounds << 2));125for (u = 0; u < 16; u ++) {126buf[u] = state[u];127}128}129130131