📄 rijndael.c
字号:
/* * rijndael.c * * An implemnetation of the RIJNDAEL cipher. * * David A. McGrew * Cisco Systems, Inc. *//* * * Copyright (c) 2001, 2002, Cisco Systems, Inc. * 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. * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * 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 HOLDERS 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 "rijndael.h"/* functions for precomputing rijndael values *//* * A[] is the 8 x 8 binary matrix (represented as an array of columns, * where each column is an octet) which defines the affine * transformation used in the RIJNDAEL substitution table (Section * 4.2.1 of the spec). */octet_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 };/* * b is the 8 bit vector (represented as an octet) used in the affine * transform described above. */octet_t b = 99;#if RIJNDAEL_USE_PRECOMPUTED_TABLES /* use the precomputed tables in rijndael_tables.c */unsigned char rijndael_sbox[256];unsigned long T0[256], T1[256], T2[256], T3[256]; #else /* compute the tables at init time, using rijndael_comptue_tables() */extern unsigned char rijndael_sbox[256];extern unsigned long T0[256], T1[256], T2[256], T3[256], T4[256]; voidrijndael_init_sbox() { int i; octet_t x; for (i=0; i < 256; i++) { x = gf2_8_compute_inverse((gf2_8)i); x = A_times_x_plus_b(A, x, b); rijndael_sbox[i] = x; }}voidrijndael_compute_tables() { int i; unsigned long x1, x2, x3; v32_t tmp; /* initialize substitution table */ rijndael_init_sbox(); /* combine sbox with linear operations to form 8-bit to 32-bit tables */ for (i=0; i < 256; i++) { x1 = rijndael_sbox[i]; x2 = gf2_8_shift(x1); x3 = x2 ^ x1; tmp.octet[0] = x2; tmp.octet[1] = x1; tmp.octet[2] = x1; tmp.octet[3] = x3; T0[i] = tmp.value; tmp.octet[0] = x3; tmp.octet[1] = x2; tmp.octet[2] = x1; tmp.octet[3] = x1; T1[i] = tmp.value; tmp.octet[0] = x1; tmp.octet[1] = x3; tmp.octet[2] = x2; tmp.octet[3] = x1; T2[i] = tmp.value; tmp.octet[0] = x1; tmp.octet[1] = x1; tmp.octet[2] = x3; tmp.octet[3] = x2; T3[i] = tmp.value; }}#endif/* rijndael internals */inline voidrijndael_expand_key(const v128_t key, rijndael_expanded_key expanded_key) { int i; gf2_8 rc; /* initialize round constant */ rc = 1; expanded_key[0].v32[0] = key.v32[0]; expanded_key[0].v32[1] = key.v32[1]; expanded_key[0].v32[2] = key.v32[2]; expanded_key[0].v32[3] = key.v32[3]; /* loop over round keys */ for (i=1; i < 11; i++) { /* munge first word of round key */ expanded_key[i].octet[0] = rijndael_sbox[expanded_key[i-1].octet[13]] ^ rc; expanded_key[i].octet[1] = rijndael_sbox[expanded_key[i-1].octet[14]]; expanded_key[i].octet[2] = rijndael_sbox[expanded_key[i-1].octet[15]]; expanded_key[i].octet[3] = rijndael_sbox[expanded_key[i-1].octet[12]]; expanded_key[i].v32[0] ^= expanded_key[i-1].v32[0]; /* set remaining 32 bit words to the exor of the one previous with * the one four words previous */ expanded_key[i].v32[1] = expanded_key[i].v32[0] ^ expanded_key[i-1].v32[1]; expanded_key[i].v32[2] = expanded_key[i].v32[1] ^ expanded_key[i-1].v32[2]; expanded_key[i].v32[3] = expanded_key[i].v32[2] ^ expanded_key[i-1].v32[3]; /* modify round constant */ rc = gf2_8_shift(rc); }}#if CPU_CISCinline voidrijndael_round(v128_t *state, const v128_t round_key) { unsigned long column0, column1, column2, column3; /* compute the columns of the output square in terms of the octets of state, using the tables T0, T1, T2, T3 */ column0 = T0[state->octet[0]] ^ T1[state->octet[5]] ^ T2[state->octet[10]] ^ T3[state->octet[15]]; column1 = T0[state->octet[4]] ^ T1[state->octet[9]] ^ T2[state->octet[14]] ^ T3[state->octet[3]]; column2 = T0[state->octet[8]] ^ T1[state->octet[13]] ^ T2[state->octet[2]] ^ T3[state->octet[7]]; column3 = T0[state->octet[12]] ^ T1[state->octet[1]] ^ T2[state->octet[6]] ^ T3[state->octet[11]]; state->v32[0] = column0 ^ round_key.v32[0]; state->v32[1] = column1 ^ round_key.v32[1]; state->v32[2] = column2 ^ round_key.v32[2]; state->v32[3] = column3 ^ round_key.v32[3]; }inline voidrijndael_final_round(v128_t *state, v128_t round_key) { octet_t tmp; /* byte substitutions and row shifts */ /* first row - no shift */ state->octet[0] = rijndael_sbox[state->octet[0]]; state->octet[4] = rijndael_sbox[state->octet[4]]; state->octet[8] = rijndael_sbox[state->octet[8]]; state->octet[12] = rijndael_sbox[state->octet[12]]; /* second row - shift one left */ tmp = rijndael_sbox[state->octet[1]]; state->octet[1] = rijndael_sbox[state->octet[5]]; state->octet[5] = rijndael_sbox[state->octet[9]]; state->octet[9] = rijndael_sbox[state->octet[13]]; state->octet[13] = tmp; /* third row - shift two left */ tmp = rijndael_sbox[state->octet[10]]; state->octet[10] = rijndael_sbox[state->octet[2]]; state->octet[2] = tmp; tmp = rijndael_sbox[state->octet[14]]; state->octet[14] = rijndael_sbox[state->octet[6]]; state->octet[6] = tmp; /* fourth row - shift three left */ tmp = rijndael_sbox[state->octet[15]]; state->octet[15] = rijndael_sbox[state->octet[11]]; state->octet[11] = rijndael_sbox[state->octet[7]]; state->octet[7] = rijndael_sbox[state->octet[3]]; state->octet[3] = tmp; v128_xor_eq(state, &round_key);}#else if CPU_RISCinline voidrijndael_round(v128_t *state, const v128_t round_key) { unsigned long column0, column1, column2, column3; /* compute the columns of the output square in terms of the octets of state, using the tables T0, T1, T2, T3 */ column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff] ^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff]; column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] ^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff]; column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] ^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff]; column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] ^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff]; state->v32[0] = column0 ^ round_key.v32[0]; state->v32[1] = column1 ^ round_key.v32[1]; state->v32[2] = column2 ^ round_key.v32[2]; state->v32[3] = column3 ^ round_key.v32[3]; }inline voidrijndael_final_round(v128_t *state, v128_t round_key) { uint32_t tmp0, tmp1, tmp2, tmp3; tmp0 = (T4[(state->v32[0] >> 24) ] & 0xff000000) ^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) ^ (T4[(state->v32[3] ) & 0xff] & 0x000000ff) ^ round_key.v32[0]; tmp1 = (T4[(state->v32[1] >> 24) ] & 0xff000000) ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^ (T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) ^ (T4[(state->v32[0] ) & 0xff] & 0x000000ff) ^ round_key.v32[1]; tmp2 = (T4[(state->v32[2] >> 24) ] & 0xff000000) ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^ (T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) ^ (T4[(state->v32[1] ) & 0xff] & 0x000000ff) ^ round_key.v32[2]; tmp3 = (T4[(state->v32[3] >> 24) ] & 0xff000000) ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) ^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff) ^ round_key.v32[3]; state->v32[0] = tmp0; state->v32[1] = tmp1; state->v32[2] = tmp2; state->v32[3] = tmp3;}#endifinline voidrijndael_add_in_subkey(v128_t *state, v128_t round_key) { state->v32[0] ^= round_key.v32[0]; state->v32[1] ^= round_key.v32[1]; state->v32[2] ^= round_key.v32[2]; state->v32[3] ^= round_key.v32[3]; }voidrijndael_encrypt(v128_t *plaintext, const rijndael_expanded_key exp_key) { /* add in the subkey */ /* v128_xor_eq(plaintext, &exp_key[0]); */ rijndael_add_in_subkey(plaintext, exp_key[0]); /* now do nine rounds */ rijndael_round(plaintext, exp_key[1]); rijndael_round(plaintext, exp_key[2]); rijndael_round(plaintext, exp_key[3]); rijndael_round(plaintext, exp_key[4]); rijndael_round(plaintext, exp_key[5]); rijndael_round(plaintext, exp_key[6]); rijndael_round(plaintext, exp_key[7]); rijndael_round(plaintext, exp_key[8]); rijndael_round(plaintext, exp_key[9]); /* the last round is different */ rijndael_final_round(plaintext, exp_key[10]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -