Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
camellia.c
00001 /** 00002 * @file camellia.c 00003 * @brief Camellia encryption algorithm 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @section Description 00026 * 00027 * Camellia is an encryption algorithm designed to encipher and decipher 00028 * blocks of 128 bits under control of a 128/192/256-bit secret key 00029 * 00030 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00031 * @version 1.7.6 00032 **/ 00033 00034 //Switch to the appropriate trace level 00035 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00036 00037 //Dependencies 00038 #include <string.h> 00039 #include "crypto.h" 00040 #include "camellia.h" 00041 #include "debug.h" 00042 00043 //Check crypto library configuration 00044 #if (CAMELLIA_SUPPORT == ENABLED) 00045 00046 //Camellia round function 00047 #define CAMELLIA_ROUND(left1, left2, right1, right2, k1, k2) \ 00048 { \ 00049 temp1 = left1 ^ k1; \ 00050 temp2 = left2 ^ k2; \ 00051 CAMELLIA_S(temp1, temp2); \ 00052 CAMELLIA_P(temp1, temp2); \ 00053 temp1 ^= right2; \ 00054 temp2 ^= right1; \ 00055 right1 = left1; \ 00056 right2 = left2; \ 00057 left1 = temp2; \ 00058 left2 = temp1; \ 00059 } 00060 00061 //F-function 00062 #define CAMELLIA_F(xl, xr, kl, kr) \ 00063 { \ 00064 xl = xl ^ kl; \ 00065 xl = xr ^ kr; \ 00066 CAMELLIA_S(xl, xr); \ 00067 CAMELLIA_P(xl, xr); \ 00068 } 00069 00070 //FL-function 00071 #define CAMELLIA_FL(xl, xr, kl, kr) \ 00072 { \ 00073 temp1 = (xl & kl); \ 00074 xr ^= ROL32(temp1, 1); \ 00075 xl ^= (xr | kr); \ 00076 } 00077 00078 //Inverse FL-function 00079 #define CAMELLIA_INV_FL(yl, yr, kl, kr) \ 00080 { \ 00081 yl ^= (yr | kr); \ 00082 temp1 = (yl & kl); \ 00083 yr ^= ROL32(temp1, 1); \ 00084 } 00085 00086 //S-function 00087 #define CAMELLIA_S(zl, zr) \ 00088 { \ 00089 zl = (sbox1[(zl >> 24) & 0xFF] << 24) | (sbox2[(zl >> 16) & 0xFF] << 16) | \ 00090 (sbox3[(zl >> 8) & 0xFF] << 8) | sbox4[zl & 0xFF]; \ 00091 zr = (sbox2[(zr >> 24) & 0xFF] << 24) | (sbox3[(zr >> 16) & 0xFF] << 16) | \ 00092 (sbox4[(zr >> 8) & 0xFF] << 8) | sbox1[zr & 0xFF]; \ 00093 } 00094 00095 //P-function 00096 #define CAMELLIA_P(zl, zr) \ 00097 { \ 00098 zl ^= ROL32(zr, 8); \ 00099 zr ^= ROL32(zl, 16); \ 00100 zl ^= ROR32(zr, 8); \ 00101 zr ^= ROR32(zl, 8); \ 00102 } 00103 00104 //Key schedule related constants 00105 #define KL 0 00106 #define KR 4 00107 #define KA 8 00108 #define KB 12 00109 #define L 0 00110 #define R 64 00111 00112 //Key schedule for 128-bit key 00113 static const CamelliaSubkey ks1[] = 00114 { 00115 {0, KL, 0, L}, //kw1 00116 {2, KL, 0, R}, //kw2 00117 {4, KA, 0, L}, //k1 00118 {6, KA, 0, R}, //k2 00119 {8, KL, 15, L}, //k3 00120 {10, KL, 15, R}, //k4 00121 {12, KA, 15, L}, //k5 00122 {14, KA, 15, R}, //k6 00123 {16, KA, 30, L}, //ke1 00124 {18, KA, 30, R}, //ke2 00125 {20, KL, 45, L}, //k7 00126 {22, KL, 45, R}, //k8 00127 {24, KA, 45, L}, //k9 00128 {26, KL, 60, R}, //k10 00129 {28, KA, 60, L}, //k11 00130 {30, KA, 60, R}, //k12 00131 {32, KL, 77, L}, //ke3 00132 {34, KL, 77, R}, //ke4 00133 {36, KL, 94, L}, //k13 00134 {38, KL, 94, R}, //k14 00135 {40, KA, 94, L}, //k15 00136 {42, KA, 94, R}, //k16 00137 {44, KL, 111, L}, //k17 00138 {46, KL, 111, R}, //k18 00139 {48, KA, 111, L}, //kw3 00140 {50, KA, 111, R}, //kw4 00141 }; 00142 00143 //Key schedule for 192 and 256-bit keys 00144 static const CamelliaSubkey ks2[] = 00145 { 00146 {0, KL, 0, L}, //kw1 00147 {2, KL, 0, R}, //k2 00148 {4, KB, 0, L}, //k1 00149 {6, KB, 0, R}, //k2 00150 {8, KR, 15, L}, //k3 00151 {10, KR, 15, R}, //k4 00152 {12, KA, 15, L}, //k5 00153 {14, KA, 15, R}, //k6 00154 {16, KR, 30, L}, //ke1 00155 {18, KR, 30, R}, //ke2 00156 {20, KB, 30, L}, //k7 00157 {22, KB, 30, R}, //k8 00158 {24, KL, 45, L}, //k9 00159 {26, KL, 45, R}, //k10 00160 {28, KA, 45, L}, //k11 00161 {30, KA, 45, R}, //k12 00162 {32, KL, 60, L}, //ke3 00163 {34, KL, 60, R}, //ke4 00164 {36, KR, 60, L}, //k13 00165 {38, KR, 60, R}, //k14 00166 {40, KB, 60, L}, //k15 00167 {42, KB, 60, R}, //k16 00168 {44, KL, 77, L}, //k17 00169 {46, KL, 77, R}, //k18 00170 {48, KA, 77, L}, //ke5 00171 {50, KA, 77, R}, //ke6 00172 {52, KR, 94, L}, //k19 00173 {54, KR, 94, R}, //k20 00174 {56, KA, 94, L}, //k21 00175 {58, KA, 94, R}, //k22 00176 {60, KL, 111, L}, //k23 00177 {62, KL, 111, R}, //k24 00178 {64, KB, 111, L}, //kw3 00179 {66, KB, 111, R}, //kw4 00180 }; 00181 00182 //Key schedule constants 00183 static const uint32_t sigma[12] = 00184 { 00185 0xA09E667F, 0x3BCC908B, 00186 0xB67AE858, 0x4CAA73B2, 00187 0xC6EF372F, 0xE94F82BE, 00188 0x54FF53A5, 0xF1D36F1C, 00189 0x10E527FA, 0xDE682D1D, 00190 0xB05688C2, 0xB3E6C1FD 00191 }; 00192 00193 //Substitution table 1 00194 static const uint8_t sbox1[256] = 00195 { 00196 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57, 0x35, 0xEA, 0x0C, 0xAE, 0x41, 00197 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19, 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD, 00198 0x86, 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F, 0x5E, 0xC5, 0x0B, 0x1A, 00199 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D, 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D, 00200 0x8B, 0x0D, 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0, 0xB1, 0x84, 0x99, 00201 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05, 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7, 00202 0x14, 0x58, 0x3A, 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18, 0xF2, 0x22, 00203 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24, 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50, 00204 0xAA, 0xD0, 0xA0, 0x7D, 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64, 0xD2, 00205 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03, 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94, 00206 0x87, 0x5C, 0x83, 0x02, 0xCD, 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2, 00207 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F, 0x4B, 0x13, 0xBE, 0x63, 0x2E, 00208 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E, 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59, 00209 0x78, 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42, 0x88, 0xA2, 0x8D, 0xFA, 00210 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC, 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4, 00211 0x40, 0x28, 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77, 0xC7, 0x80, 0x9E 00212 }; 00213 00214 //Substitution table 2 00215 static const uint8_t sbox2[256] = 00216 { 00217 0xE0, 0x05, 0x58, 0xD9, 0x67, 0x4E, 0x81, 0xCB, 0xC9, 0x0B, 0xAE, 0x6A, 0xD5, 0x18, 0x5D, 0x82, 00218 0x46, 0xDF, 0xD6, 0x27, 0x8A, 0x32, 0x4B, 0x42, 0xDB, 0x1C, 0x9E, 0x9C, 0x3A, 0xCA, 0x25, 0x7B, 00219 0x0D, 0x71, 0x5F, 0x1F, 0xF8, 0xD7, 0x3E, 0x9D, 0x7C, 0x60, 0xB9, 0xBE, 0xBC, 0x8B, 0x16, 0x34, 00220 0x4D, 0xC3, 0x72, 0x95, 0xAB, 0x8E, 0xBA, 0x7A, 0xB3, 0x02, 0xB4, 0xAD, 0xA2, 0xAC, 0xD8, 0x9A, 00221 0x17, 0x1A, 0x35, 0xCC, 0xF7, 0x99, 0x61, 0x5A, 0xE8, 0x24, 0x56, 0x40, 0xE1, 0x63, 0x09, 0x33, 00222 0xBF, 0x98, 0x97, 0x85, 0x68, 0xFC, 0xEC, 0x0A, 0xDA, 0x6F, 0x53, 0x62, 0xA3, 0x2E, 0x08, 0xAF, 00223 0x28, 0xB0, 0x74, 0xC2, 0xBD, 0x36, 0x22, 0x38, 0x64, 0x1E, 0x39, 0x2C, 0xA6, 0x30, 0xE5, 0x44, 00224 0xFD, 0x88, 0x9F, 0x65, 0x87, 0x6B, 0xF4, 0x23, 0x48, 0x10, 0xD1, 0x51, 0xC0, 0xF9, 0xD2, 0xA0, 00225 0x55, 0xA1, 0x41, 0xFA, 0x43, 0x13, 0xC4, 0x2F, 0xA8, 0xB6, 0x3C, 0x2B, 0xC1, 0xFF, 0xC8, 0xA5, 00226 0x20, 0x89, 0x00, 0x90, 0x47, 0xEF, 0xEA, 0xB7, 0x15, 0x06, 0xCD, 0xB5, 0x12, 0x7E, 0xBB, 0x29, 00227 0x0F, 0xB8, 0x07, 0x04, 0x9B, 0x94, 0x21, 0x66, 0xE6, 0xCE, 0xED, 0xE7, 0x3B, 0xFE, 0x7F, 0xC5, 00228 0xA4, 0x37, 0xB1, 0x4C, 0x91, 0x6E, 0x8D, 0x76, 0x03, 0x2D, 0xDE, 0x96, 0x26, 0x7D, 0xC6, 0x5C, 00229 0xD3, 0xF2, 0x4F, 0x19, 0x3F, 0xDC, 0x79, 0x1D, 0x52, 0xEB, 0xF3, 0x6D, 0x5E, 0xFB, 0x69, 0xB2, 00230 0xF0, 0x31, 0x0C, 0xD4, 0xCF, 0x8C, 0xE2, 0x75, 0xA9, 0x4A, 0x57, 0x84, 0x11, 0x45, 0x1B, 0xF5, 00231 0xE4, 0x0E, 0x73, 0xAA, 0xF1, 0xDD, 0x59, 0x14, 0x6C, 0x92, 0x54, 0xD0, 0x78, 0x70, 0xE3, 0x49, 00232 0x80, 0x50, 0xA7, 0xF6, 0x77, 0x93, 0x86, 0x83, 0x2A, 0xC7, 0x5B, 0xE9, 0xEE, 0x8F, 0x01, 0x3D 00233 }; 00234 00235 //Substitution table 3 00236 static const uint8_t sbox3[256] = 00237 { 00238 0x38, 0x41, 0x16, 0x76, 0xD9, 0x93, 0x60, 0xF2, 0x72, 0xC2, 0xAB, 0x9A, 0x75, 0x06, 0x57, 0xA0, 00239 0x91, 0xF7, 0xB5, 0xC9, 0xA2, 0x8C, 0xD2, 0x90, 0xF6, 0x07, 0xA7, 0x27, 0x8E, 0xB2, 0x49, 0xDE, 00240 0x43, 0x5C, 0xD7, 0xC7, 0x3E, 0xF5, 0x8F, 0x67, 0x1F, 0x18, 0x6E, 0xAF, 0x2F, 0xE2, 0x85, 0x0D, 00241 0x53, 0xF0, 0x9C, 0x65, 0xEA, 0xA3, 0xAE, 0x9E, 0xEC, 0x80, 0x2D, 0x6B, 0xA8, 0x2B, 0x36, 0xA6, 00242 0xC5, 0x86, 0x4D, 0x33, 0xFD, 0x66, 0x58, 0x96, 0x3A, 0x09, 0x95, 0x10, 0x78, 0xD8, 0x42, 0xCC, 00243 0xEF, 0x26, 0xE5, 0x61, 0x1A, 0x3F, 0x3B, 0x82, 0xB6, 0xDB, 0xD4, 0x98, 0xE8, 0x8B, 0x02, 0xEB, 00244 0x0A, 0x2C, 0x1D, 0xB0, 0x6F, 0x8D, 0x88, 0x0E, 0x19, 0x87, 0x4E, 0x0B, 0xA9, 0x0C, 0x79, 0x11, 00245 0x7F, 0x22, 0xE7, 0x59, 0xE1, 0xDA, 0x3D, 0xC8, 0x12, 0x04, 0x74, 0x54, 0x30, 0x7E, 0xB4, 0x28, 00246 0x55, 0x68, 0x50, 0xBE, 0xD0, 0xC4, 0x31, 0xCB, 0x2A, 0xAD, 0x0F, 0xCA, 0x70, 0xFF, 0x32, 0x69, 00247 0x08, 0x62, 0x00, 0x24, 0xD1, 0xFB, 0xBA, 0xED, 0x45, 0x81, 0x73, 0x6D, 0x84, 0x9F, 0xEE, 0x4A, 00248 0xC3, 0x2E, 0xC1, 0x01, 0xE6, 0x25, 0x48, 0x99, 0xB9, 0xB3, 0x7B, 0xF9, 0xCE, 0xBF, 0xDF, 0x71, 00249 0x29, 0xCD, 0x6C, 0x13, 0x64, 0x9B, 0x63, 0x9D, 0xC0, 0x4B, 0xB7, 0xA5, 0x89, 0x5F, 0xB1, 0x17, 00250 0xF4, 0xBC, 0xD3, 0x46, 0xCF, 0x37, 0x5E, 0x47, 0x94, 0xFA, 0xFC, 0x5B, 0x97, 0xFE, 0x5A, 0xAC, 00251 0x3C, 0x4C, 0x03, 0x35, 0xF3, 0x23, 0xB8, 0x5D, 0x6A, 0x92, 0xD5, 0x21, 0x44, 0x51, 0xC6, 0x7D, 00252 0x39, 0x83, 0xDC, 0xAA, 0x7C, 0x77, 0x56, 0x05, 0x1B, 0xA4, 0x15, 0x34, 0x1E, 0x1C, 0xF8, 0x52, 00253 0x20, 0x14, 0xE9, 0xBD, 0xDD, 0xE4, 0xA1, 0xE0, 0x8A, 0xF1, 0xD6, 0x7A, 0xBB, 0xE3, 0x40, 0x4F 00254 }; 00255 00256 //Substitution table 4 00257 static const uint8_t sbox4[256] = 00258 { 00259 0x70, 0x2C, 0xB3, 0xC0, 0xE4, 0x57, 0xEA, 0xAE, 0x23, 0x6B, 0x45, 0xA5, 0xED, 0x4F, 0x1D, 0x92, 00260 0x86, 0xAF, 0x7C, 0x1F, 0x3E, 0xDC, 0x5E, 0x0B, 0xA6, 0x39, 0xD5, 0x5D, 0xD9, 0x5A, 0x51, 0x6C, 00261 0x8B, 0x9A, 0xFB, 0xB0, 0x74, 0x2B, 0xF0, 0x84, 0xDF, 0xCB, 0x34, 0x76, 0x6D, 0xA9, 0xD1, 0x04, 00262 0x14, 0x3A, 0xDE, 0x11, 0x32, 0x9C, 0x53, 0xF2, 0xFE, 0xCF, 0xC3, 0x7A, 0x24, 0xE8, 0x60, 0x69, 00263 0xAA, 0xA0, 0xA1, 0x62, 0x54, 0x1E, 0xE0, 0x64, 0x10, 0x00, 0xA3, 0x75, 0x8A, 0xE6, 0x09, 0xDD, 00264 0x87, 0x83, 0xCD, 0x90, 0x73, 0xF6, 0x9D, 0xBF, 0x52, 0xD8, 0xC8, 0xC6, 0x81, 0x6F, 0x13, 0x63, 00265 0xE9, 0xA7, 0x9F, 0xBC, 0x29, 0xF9, 0x2F, 0xB4, 0x78, 0x06, 0xE7, 0x71, 0xD4, 0xAB, 0x88, 0x8D, 00266 0x72, 0xB9, 0xF8, 0xAC, 0x36, 0x2A, 0x3C, 0xF1, 0x40, 0xD3, 0xBB, 0x43, 0x15, 0xAD, 0x77, 0x80, 00267 0x82, 0xEC, 0x27, 0xE5, 0x85, 0x35, 0x0C, 0x41, 0xEF, 0x93, 0x19, 0x21, 0x0E, 0x4E, 0x65, 0xBD, 00268 0xB8, 0x8F, 0xEB, 0xCE, 0x30, 0x5F, 0xC5, 0x1A, 0xE1, 0xCA, 0x47, 0x3D, 0x01, 0xD6, 0x56, 0x4D, 00269 0x0D, 0x66, 0xCC, 0x2D, 0x12, 0x20, 0xB1, 0x99, 0x4C, 0xC2, 0x7E, 0x05, 0xB7, 0x31, 0x17, 0xD7, 00270 0x58, 0x61, 0x1B, 0x1C, 0x0F, 0x16, 0x18, 0x22, 0x44, 0xB2, 0xB5, 0x91, 0x08, 0xA8, 0xFC, 0x50, 00271 0xD0, 0x7D, 0x89, 0x97, 0x5B, 0x95, 0xFF, 0xD2, 0xC4, 0x48, 0xF7, 0xDB, 0x03, 0xDA, 0x3F, 0x94, 00272 0x5C, 0x02, 0x4A, 0x33, 0x67, 0xF3, 0x7F, 0xE2, 0x9B, 0x26, 0x37, 0x3B, 0x96, 0x4B, 0xBE, 0x2E, 00273 0x79, 0x8C, 0x6E, 0x8E, 0xF5, 0xB6, 0xFD, 0x59, 0x98, 0x6A, 0x46, 0xBA, 0x25, 0x42, 0xA2, 0xFA, 00274 0x07, 0x55, 0xEE, 0x0A, 0x49, 0x68, 0x38, 0xA4, 0x28, 0x7B, 0xC9, 0xC1, 0xE3, 0xF4, 0xC7, 0x9E 00275 }; 00276 00277 //Common interface for encryption algorithms 00278 const CipherAlgo camelliaCipherAlgo = 00279 { 00280 "CAMELLIA", 00281 sizeof(CamelliaContext), 00282 CIPHER_ALGO_TYPE_BLOCK, 00283 CAMELLIA_BLOCK_SIZE, 00284 (CipherAlgoInit) camelliaInit, 00285 NULL, 00286 NULL, 00287 (CipherAlgoEncryptBlock) camelliaEncryptBlock, 00288 (CipherAlgoDecryptBlock) camelliaDecryptBlock 00289 }; 00290 00291 00292 /** 00293 * @brief Initialize a Camellia context using the supplied key 00294 * @param[in] context Pointer to the Camellia context to initialize 00295 * @param[in] key Pointer to the key 00296 * @param[in] keyLength Length of the key 00297 * @return Error code 00298 **/ 00299 00300 error_t camelliaInit(CamelliaContext *context, const uint8_t *key, size_t keyLength) 00301 { 00302 uint_t i; 00303 uint32_t temp1; 00304 uint32_t temp2; 00305 uint32_t *k; 00306 const CamelliaSubkey *p; 00307 00308 //18 rounds are required for 128-bit key 00309 if(keyLength == 16) 00310 context->nr = 18; 00311 //24 rounds are required for 192 and 256-bit keys 00312 else if(keyLength == 24 || keyLength == 32) 00313 context->nr = 24; 00314 //Key length is not supported... 00315 else 00316 return ERROR_INVALID_KEY_LENGTH; 00317 00318 //Point to KA, KB, KL and KR 00319 k = context->k; 00320 //Clear key contents 00321 memset(k, 0, 64); 00322 //Save the supplied secret key 00323 memcpy(k, key, keyLength); 00324 00325 //192-bit keys require special processing 00326 if(keyLength == 24) 00327 { 00328 //Form a 256-bit key 00329 k[KR + 2] = ~k[KR + 0]; 00330 k[KR + 3] = ~k[KR + 1]; 00331 } 00332 00333 //XOR KL and KR before applying the rounds 00334 for(i = 0; i < 4; i++) 00335 { 00336 k[KL + i] = betoh32(k[KL + i]); 00337 k[KR + i] = betoh32(k[KR + i]); 00338 k[KB + i] = k[KL + i] ^ k[KR + i]; 00339 } 00340 00341 //Generate the 128-bit keys KA and KB 00342 for(i = 0; i < 6; i++) 00343 { 00344 //Apply round function 00345 CAMELLIA_ROUND(k[KB + 0], k[KB + 1], k[KB + 2], k[KB + 3], sigma[2 * i], sigma[2 * i + 1]); 00346 00347 //The 2nd round requires special processing 00348 if(i == 1) 00349 { 00350 //The result is XORed with KL 00351 k[KB + 0] ^= k[KL + 0]; 00352 k[KB + 1] ^= k[KL + 1]; 00353 k[KB + 2] ^= k[KL + 2]; 00354 k[KB + 3] ^= k[KL + 3]; 00355 } 00356 //The 4th round requires special processing 00357 else if(i == 3) 00358 { 00359 //Save KA after the 4th round 00360 memcpy(k + KA, k + KB, 16); 00361 //The result is XORed with KR 00362 k[KB + 0] ^= k[KR + 0]; 00363 k[KB + 1] ^= k[KR + 1]; 00364 k[KB + 2] ^= k[KR + 2]; 00365 k[KB + 3] ^= k[KR + 3]; 00366 } 00367 } 00368 00369 //The key schedule depends on the length of key 00370 if(keyLength == 16) 00371 { 00372 //Key schedule for 128-bit key 00373 i = arraysize(ks1); 00374 p = ks1; 00375 } 00376 else 00377 { 00378 //Key schedule for 192 and 256-bit keys 00379 i = arraysize(ks2); 00380 p = ks2; 00381 } 00382 00383 //Generate subkeys 00384 while(i > 0) 00385 { 00386 //Calculate the shift count 00387 uint_t n = (p->shift + p->position) / 32; 00388 uint_t m = (p->shift + p->position) % 32; 00389 //Point to KL, KR, KA or KB 00390 k = context->k + p->key; 00391 00392 //Generate the current subkey 00393 if(m == 0) 00394 { 00395 context->ks[p->index] = k[n % 4]; 00396 context->ks[p->index + 1] = k[(n + 1) % 4]; 00397 } 00398 else 00399 { 00400 context->ks[p->index] = (k[n % 4] << m) | (k[(n + 1) % 4] >> (32 - m)); 00401 context->ks[p->index + 1] = (k[(n + 1) % 4] << m) | (k[(n + 2) % 4] >> (32 - m)); 00402 } 00403 00404 //Next subkey 00405 p++; 00406 i--; 00407 } 00408 00409 //No error to report 00410 return NO_ERROR; 00411 } 00412 00413 00414 /** 00415 * @brief Encrypt a 16-byte block using Camellia algorithm 00416 * @param[in] context Pointer to the Camellia context 00417 * @param[in] input Plaintext block to encrypt 00418 * @param[out] output Ciphertext block resulting from encryption 00419 **/ 00420 00421 void camelliaEncryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output) 00422 { 00423 uint_t i; 00424 uint32_t temp1; 00425 uint32_t temp2; 00426 uint32_t *ks; 00427 00428 //The plaintext is separated into two parts (L and R) 00429 uint32_t left1 = LOAD32BE(input + 0); 00430 uint32_t left2 = LOAD32BE(input + 4); 00431 uint32_t right1 = LOAD32BE(input + 8); 00432 uint32_t right2 = LOAD32BE(input + 12); 00433 00434 //The key schedule must be applied in ascending order 00435 ks = context->ks; 00436 00437 //XOR plaintext with kw1 and kw2 00438 left1 ^= ks[0]; 00439 left2 ^= ks[1]; 00440 right1 ^= ks[2]; 00441 right2 ^= ks[3]; 00442 //Advance current location in key schedule 00443 ks += 4; 00444 00445 //Apply round function 18 or 24 times depending on the key length 00446 for(i = context->nr; i > 0; i--) 00447 { 00448 //Apply round function 00449 CAMELLIA_ROUND(left1, left2, right1, right2, ks[0], ks[1]); 00450 //Advance current location in key schedule 00451 ks += 2; 00452 00453 //6th, 12th and 18th rounds require special processing 00454 if(i == 7 || i == 13 || i == 19) 00455 { 00456 //Apply FL-function 00457 CAMELLIA_FL(left1, left2, ks[0], ks[1]) 00458 //Apply inverse FL-function 00459 CAMELLIA_INV_FL(right1, right2, ks[2], ks[3]) 00460 //Advance current location in key schedule 00461 ks += 4; 00462 } 00463 } 00464 00465 //XOR operation with kw3 and kw4 00466 right1 ^= ks[0]; 00467 right2 ^= ks[1]; 00468 left1 ^= ks[2]; 00469 left2 ^= ks[3]; 00470 00471 //The resulting value is the ciphertext 00472 STORE32BE(right1, output + 0); 00473 STORE32BE(right2, output + 4); 00474 STORE32BE(left1, output + 8); 00475 STORE32BE(left2, output + 12); 00476 } 00477 00478 00479 /** 00480 * @brief Decrypt a 16-byte block using Camellia algorithm 00481 * @param[in] context Pointer to the Camellia context 00482 * @param[in] input Ciphertext block to decrypt 00483 * @param[out] output Plaintext block resulting from decryption 00484 **/ 00485 00486 void camelliaDecryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output) 00487 { 00488 uint_t i; 00489 uint32_t temp1; 00490 uint32_t temp2; 00491 uint32_t *ks; 00492 00493 //The ciphertext is separated into two parts (L and R) 00494 uint32_t right1 = LOAD32BE(input + 0); 00495 uint32_t right2 = LOAD32BE(input + 4); 00496 uint32_t left1 = LOAD32BE(input + 8); 00497 uint32_t left2 = LOAD32BE(input + 12); 00498 00499 //The key schedule must be applied in reverse order 00500 ks = (context->nr == 18) ? (context->ks + 48) : (context->ks + 64); 00501 00502 //XOR ciphertext with kw3 and kw4 00503 right1 ^= ks[0]; 00504 right2 ^= ks[1]; 00505 left1 ^= ks[2]; 00506 left2 ^= ks[3]; 00507 00508 //Apply round function 18 or 24 times depending on the key length 00509 for(i = context->nr; i > 0; i--) 00510 { 00511 //Update current location in key schedule 00512 ks -= 2; 00513 //Apply round function 00514 CAMELLIA_ROUND(right1, right2, left1, left2, ks[0], ks[1]); 00515 00516 //6th, 12th and 18th rounds require special processing 00517 if(i == 7 || i == 13 || i == 19) 00518 { 00519 //Update current location in key schedule 00520 ks -= 4; 00521 //Apply FL-function 00522 CAMELLIA_FL(right1, right2, ks[2], ks[3]) 00523 //Apply inverse FL-function 00524 CAMELLIA_INV_FL(left1, left2, ks[0], ks[1]) 00525 } 00526 } 00527 00528 //Update current location in key schedule 00529 ks -= 4; 00530 //XOR operation with kw1 and kw2 00531 left1 ^= ks[0]; 00532 left2 ^= ks[1]; 00533 right1 ^= ks[2]; 00534 right2 ^= ks[3]; 00535 00536 //The resulting value is the plaintext 00537 STORE32BE(left1, output + 0); 00538 STORE32BE(left2, output + 4); 00539 STORE32BE(right1, output + 8); 00540 STORE32BE(right2, output + 12); 00541 } 00542 00543 #endif 00544
Generated on Tue Jul 12 2022 17:10:12 by
1.7.2