Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file camellia.c
Sergunb 0:8918a71cdbe9 3 * @brief Camellia encryption algorithm
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneCrypto Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @section Description
Sergunb 0:8918a71cdbe9 26 *
Sergunb 0:8918a71cdbe9 27 * Camellia is an encryption algorithm designed to encipher and decipher
Sergunb 0:8918a71cdbe9 28 * blocks of 128 bits under control of a 128/192/256-bit secret key
Sergunb 0:8918a71cdbe9 29 *
Sergunb 0:8918a71cdbe9 30 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 31 * @version 1.7.6
Sergunb 0:8918a71cdbe9 32 **/
Sergunb 0:8918a71cdbe9 33
Sergunb 0:8918a71cdbe9 34 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 35 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 36
Sergunb 0:8918a71cdbe9 37 //Dependencies
Sergunb 0:8918a71cdbe9 38 #include <string.h>
Sergunb 0:8918a71cdbe9 39 #include "crypto.h"
Sergunb 0:8918a71cdbe9 40 #include "camellia.h"
Sergunb 0:8918a71cdbe9 41 #include "debug.h"
Sergunb 0:8918a71cdbe9 42
Sergunb 0:8918a71cdbe9 43 //Check crypto library configuration
Sergunb 0:8918a71cdbe9 44 #if (CAMELLIA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 45
Sergunb 0:8918a71cdbe9 46 //Camellia round function
Sergunb 0:8918a71cdbe9 47 #define CAMELLIA_ROUND(left1, left2, right1, right2, k1, k2) \
Sergunb 0:8918a71cdbe9 48 { \
Sergunb 0:8918a71cdbe9 49 temp1 = left1 ^ k1; \
Sergunb 0:8918a71cdbe9 50 temp2 = left2 ^ k2; \
Sergunb 0:8918a71cdbe9 51 CAMELLIA_S(temp1, temp2); \
Sergunb 0:8918a71cdbe9 52 CAMELLIA_P(temp1, temp2); \
Sergunb 0:8918a71cdbe9 53 temp1 ^= right2; \
Sergunb 0:8918a71cdbe9 54 temp2 ^= right1; \
Sergunb 0:8918a71cdbe9 55 right1 = left1; \
Sergunb 0:8918a71cdbe9 56 right2 = left2; \
Sergunb 0:8918a71cdbe9 57 left1 = temp2; \
Sergunb 0:8918a71cdbe9 58 left2 = temp1; \
Sergunb 0:8918a71cdbe9 59 }
Sergunb 0:8918a71cdbe9 60
Sergunb 0:8918a71cdbe9 61 //F-function
Sergunb 0:8918a71cdbe9 62 #define CAMELLIA_F(xl, xr, kl, kr) \
Sergunb 0:8918a71cdbe9 63 { \
Sergunb 0:8918a71cdbe9 64 xl = xl ^ kl; \
Sergunb 0:8918a71cdbe9 65 xl = xr ^ kr; \
Sergunb 0:8918a71cdbe9 66 CAMELLIA_S(xl, xr); \
Sergunb 0:8918a71cdbe9 67 CAMELLIA_P(xl, xr); \
Sergunb 0:8918a71cdbe9 68 }
Sergunb 0:8918a71cdbe9 69
Sergunb 0:8918a71cdbe9 70 //FL-function
Sergunb 0:8918a71cdbe9 71 #define CAMELLIA_FL(xl, xr, kl, kr) \
Sergunb 0:8918a71cdbe9 72 { \
Sergunb 0:8918a71cdbe9 73 temp1 = (xl & kl); \
Sergunb 0:8918a71cdbe9 74 xr ^= ROL32(temp1, 1); \
Sergunb 0:8918a71cdbe9 75 xl ^= (xr | kr); \
Sergunb 0:8918a71cdbe9 76 }
Sergunb 0:8918a71cdbe9 77
Sergunb 0:8918a71cdbe9 78 //Inverse FL-function
Sergunb 0:8918a71cdbe9 79 #define CAMELLIA_INV_FL(yl, yr, kl, kr) \
Sergunb 0:8918a71cdbe9 80 { \
Sergunb 0:8918a71cdbe9 81 yl ^= (yr | kr); \
Sergunb 0:8918a71cdbe9 82 temp1 = (yl & kl); \
Sergunb 0:8918a71cdbe9 83 yr ^= ROL32(temp1, 1); \
Sergunb 0:8918a71cdbe9 84 }
Sergunb 0:8918a71cdbe9 85
Sergunb 0:8918a71cdbe9 86 //S-function
Sergunb 0:8918a71cdbe9 87 #define CAMELLIA_S(zl, zr) \
Sergunb 0:8918a71cdbe9 88 { \
Sergunb 0:8918a71cdbe9 89 zl = (sbox1[(zl >> 24) & 0xFF] << 24) | (sbox2[(zl >> 16) & 0xFF] << 16) | \
Sergunb 0:8918a71cdbe9 90 (sbox3[(zl >> 8) & 0xFF] << 8) | sbox4[zl & 0xFF]; \
Sergunb 0:8918a71cdbe9 91 zr = (sbox2[(zr >> 24) & 0xFF] << 24) | (sbox3[(zr >> 16) & 0xFF] << 16) | \
Sergunb 0:8918a71cdbe9 92 (sbox4[(zr >> 8) & 0xFF] << 8) | sbox1[zr & 0xFF]; \
Sergunb 0:8918a71cdbe9 93 }
Sergunb 0:8918a71cdbe9 94
Sergunb 0:8918a71cdbe9 95 //P-function
Sergunb 0:8918a71cdbe9 96 #define CAMELLIA_P(zl, zr) \
Sergunb 0:8918a71cdbe9 97 { \
Sergunb 0:8918a71cdbe9 98 zl ^= ROL32(zr, 8); \
Sergunb 0:8918a71cdbe9 99 zr ^= ROL32(zl, 16); \
Sergunb 0:8918a71cdbe9 100 zl ^= ROR32(zr, 8); \
Sergunb 0:8918a71cdbe9 101 zr ^= ROR32(zl, 8); \
Sergunb 0:8918a71cdbe9 102 }
Sergunb 0:8918a71cdbe9 103
Sergunb 0:8918a71cdbe9 104 //Key schedule related constants
Sergunb 0:8918a71cdbe9 105 #define KL 0
Sergunb 0:8918a71cdbe9 106 #define KR 4
Sergunb 0:8918a71cdbe9 107 #define KA 8
Sergunb 0:8918a71cdbe9 108 #define KB 12
Sergunb 0:8918a71cdbe9 109 #define L 0
Sergunb 0:8918a71cdbe9 110 #define R 64
Sergunb 0:8918a71cdbe9 111
Sergunb 0:8918a71cdbe9 112 //Key schedule for 128-bit key
Sergunb 0:8918a71cdbe9 113 static const CamelliaSubkey ks1[] =
Sergunb 0:8918a71cdbe9 114 {
Sergunb 0:8918a71cdbe9 115 {0, KL, 0, L}, //kw1
Sergunb 0:8918a71cdbe9 116 {2, KL, 0, R}, //kw2
Sergunb 0:8918a71cdbe9 117 {4, KA, 0, L}, //k1
Sergunb 0:8918a71cdbe9 118 {6, KA, 0, R}, //k2
Sergunb 0:8918a71cdbe9 119 {8, KL, 15, L}, //k3
Sergunb 0:8918a71cdbe9 120 {10, KL, 15, R}, //k4
Sergunb 0:8918a71cdbe9 121 {12, KA, 15, L}, //k5
Sergunb 0:8918a71cdbe9 122 {14, KA, 15, R}, //k6
Sergunb 0:8918a71cdbe9 123 {16, KA, 30, L}, //ke1
Sergunb 0:8918a71cdbe9 124 {18, KA, 30, R}, //ke2
Sergunb 0:8918a71cdbe9 125 {20, KL, 45, L}, //k7
Sergunb 0:8918a71cdbe9 126 {22, KL, 45, R}, //k8
Sergunb 0:8918a71cdbe9 127 {24, KA, 45, L}, //k9
Sergunb 0:8918a71cdbe9 128 {26, KL, 60, R}, //k10
Sergunb 0:8918a71cdbe9 129 {28, KA, 60, L}, //k11
Sergunb 0:8918a71cdbe9 130 {30, KA, 60, R}, //k12
Sergunb 0:8918a71cdbe9 131 {32, KL, 77, L}, //ke3
Sergunb 0:8918a71cdbe9 132 {34, KL, 77, R}, //ke4
Sergunb 0:8918a71cdbe9 133 {36, KL, 94, L}, //k13
Sergunb 0:8918a71cdbe9 134 {38, KL, 94, R}, //k14
Sergunb 0:8918a71cdbe9 135 {40, KA, 94, L}, //k15
Sergunb 0:8918a71cdbe9 136 {42, KA, 94, R}, //k16
Sergunb 0:8918a71cdbe9 137 {44, KL, 111, L}, //k17
Sergunb 0:8918a71cdbe9 138 {46, KL, 111, R}, //k18
Sergunb 0:8918a71cdbe9 139 {48, KA, 111, L}, //kw3
Sergunb 0:8918a71cdbe9 140 {50, KA, 111, R}, //kw4
Sergunb 0:8918a71cdbe9 141 };
Sergunb 0:8918a71cdbe9 142
Sergunb 0:8918a71cdbe9 143 //Key schedule for 192 and 256-bit keys
Sergunb 0:8918a71cdbe9 144 static const CamelliaSubkey ks2[] =
Sergunb 0:8918a71cdbe9 145 {
Sergunb 0:8918a71cdbe9 146 {0, KL, 0, L}, //kw1
Sergunb 0:8918a71cdbe9 147 {2, KL, 0, R}, //k2
Sergunb 0:8918a71cdbe9 148 {4, KB, 0, L}, //k1
Sergunb 0:8918a71cdbe9 149 {6, KB, 0, R}, //k2
Sergunb 0:8918a71cdbe9 150 {8, KR, 15, L}, //k3
Sergunb 0:8918a71cdbe9 151 {10, KR, 15, R}, //k4
Sergunb 0:8918a71cdbe9 152 {12, KA, 15, L}, //k5
Sergunb 0:8918a71cdbe9 153 {14, KA, 15, R}, //k6
Sergunb 0:8918a71cdbe9 154 {16, KR, 30, L}, //ke1
Sergunb 0:8918a71cdbe9 155 {18, KR, 30, R}, //ke2
Sergunb 0:8918a71cdbe9 156 {20, KB, 30, L}, //k7
Sergunb 0:8918a71cdbe9 157 {22, KB, 30, R}, //k8
Sergunb 0:8918a71cdbe9 158 {24, KL, 45, L}, //k9
Sergunb 0:8918a71cdbe9 159 {26, KL, 45, R}, //k10
Sergunb 0:8918a71cdbe9 160 {28, KA, 45, L}, //k11
Sergunb 0:8918a71cdbe9 161 {30, KA, 45, R}, //k12
Sergunb 0:8918a71cdbe9 162 {32, KL, 60, L}, //ke3
Sergunb 0:8918a71cdbe9 163 {34, KL, 60, R}, //ke4
Sergunb 0:8918a71cdbe9 164 {36, KR, 60, L}, //k13
Sergunb 0:8918a71cdbe9 165 {38, KR, 60, R}, //k14
Sergunb 0:8918a71cdbe9 166 {40, KB, 60, L}, //k15
Sergunb 0:8918a71cdbe9 167 {42, KB, 60, R}, //k16
Sergunb 0:8918a71cdbe9 168 {44, KL, 77, L}, //k17
Sergunb 0:8918a71cdbe9 169 {46, KL, 77, R}, //k18
Sergunb 0:8918a71cdbe9 170 {48, KA, 77, L}, //ke5
Sergunb 0:8918a71cdbe9 171 {50, KA, 77, R}, //ke6
Sergunb 0:8918a71cdbe9 172 {52, KR, 94, L}, //k19
Sergunb 0:8918a71cdbe9 173 {54, KR, 94, R}, //k20
Sergunb 0:8918a71cdbe9 174 {56, KA, 94, L}, //k21
Sergunb 0:8918a71cdbe9 175 {58, KA, 94, R}, //k22
Sergunb 0:8918a71cdbe9 176 {60, KL, 111, L}, //k23
Sergunb 0:8918a71cdbe9 177 {62, KL, 111, R}, //k24
Sergunb 0:8918a71cdbe9 178 {64, KB, 111, L}, //kw3
Sergunb 0:8918a71cdbe9 179 {66, KB, 111, R}, //kw4
Sergunb 0:8918a71cdbe9 180 };
Sergunb 0:8918a71cdbe9 181
Sergunb 0:8918a71cdbe9 182 //Key schedule constants
Sergunb 0:8918a71cdbe9 183 static const uint32_t sigma[12] =
Sergunb 0:8918a71cdbe9 184 {
Sergunb 0:8918a71cdbe9 185 0xA09E667F, 0x3BCC908B,
Sergunb 0:8918a71cdbe9 186 0xB67AE858, 0x4CAA73B2,
Sergunb 0:8918a71cdbe9 187 0xC6EF372F, 0xE94F82BE,
Sergunb 0:8918a71cdbe9 188 0x54FF53A5, 0xF1D36F1C,
Sergunb 0:8918a71cdbe9 189 0x10E527FA, 0xDE682D1D,
Sergunb 0:8918a71cdbe9 190 0xB05688C2, 0xB3E6C1FD
Sergunb 0:8918a71cdbe9 191 };
Sergunb 0:8918a71cdbe9 192
Sergunb 0:8918a71cdbe9 193 //Substitution table 1
Sergunb 0:8918a71cdbe9 194 static const uint8_t sbox1[256] =
Sergunb 0:8918a71cdbe9 195 {
Sergunb 0:8918a71cdbe9 196 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57, 0x35, 0xEA, 0x0C, 0xAE, 0x41,
Sergunb 0:8918a71cdbe9 197 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19, 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD,
Sergunb 0:8918a71cdbe9 198 0x86, 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F, 0x5E, 0xC5, 0x0B, 0x1A,
Sergunb 0:8918a71cdbe9 199 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D, 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D,
Sergunb 0:8918a71cdbe9 200 0x8B, 0x0D, 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0, 0xB1, 0x84, 0x99,
Sergunb 0:8918a71cdbe9 201 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05, 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7,
Sergunb 0:8918a71cdbe9 202 0x14, 0x58, 0x3A, 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18, 0xF2, 0x22,
Sergunb 0:8918a71cdbe9 203 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24, 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50,
Sergunb 0:8918a71cdbe9 204 0xAA, 0xD0, 0xA0, 0x7D, 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64, 0xD2,
Sergunb 0:8918a71cdbe9 205 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03, 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94,
Sergunb 0:8918a71cdbe9 206 0x87, 0x5C, 0x83, 0x02, 0xCD, 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2,
Sergunb 0:8918a71cdbe9 207 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F, 0x4B, 0x13, 0xBE, 0x63, 0x2E,
Sergunb 0:8918a71cdbe9 208 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E, 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59,
Sergunb 0:8918a71cdbe9 209 0x78, 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42, 0x88, 0xA2, 0x8D, 0xFA,
Sergunb 0:8918a71cdbe9 210 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC, 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4,
Sergunb 0:8918a71cdbe9 211 0x40, 0x28, 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77, 0xC7, 0x80, 0x9E
Sergunb 0:8918a71cdbe9 212 };
Sergunb 0:8918a71cdbe9 213
Sergunb 0:8918a71cdbe9 214 //Substitution table 2
Sergunb 0:8918a71cdbe9 215 static const uint8_t sbox2[256] =
Sergunb 0:8918a71cdbe9 216 {
Sergunb 0:8918a71cdbe9 217 0xE0, 0x05, 0x58, 0xD9, 0x67, 0x4E, 0x81, 0xCB, 0xC9, 0x0B, 0xAE, 0x6A, 0xD5, 0x18, 0x5D, 0x82,
Sergunb 0:8918a71cdbe9 218 0x46, 0xDF, 0xD6, 0x27, 0x8A, 0x32, 0x4B, 0x42, 0xDB, 0x1C, 0x9E, 0x9C, 0x3A, 0xCA, 0x25, 0x7B,
Sergunb 0:8918a71cdbe9 219 0x0D, 0x71, 0x5F, 0x1F, 0xF8, 0xD7, 0x3E, 0x9D, 0x7C, 0x60, 0xB9, 0xBE, 0xBC, 0x8B, 0x16, 0x34,
Sergunb 0:8918a71cdbe9 220 0x4D, 0xC3, 0x72, 0x95, 0xAB, 0x8E, 0xBA, 0x7A, 0xB3, 0x02, 0xB4, 0xAD, 0xA2, 0xAC, 0xD8, 0x9A,
Sergunb 0:8918a71cdbe9 221 0x17, 0x1A, 0x35, 0xCC, 0xF7, 0x99, 0x61, 0x5A, 0xE8, 0x24, 0x56, 0x40, 0xE1, 0x63, 0x09, 0x33,
Sergunb 0:8918a71cdbe9 222 0xBF, 0x98, 0x97, 0x85, 0x68, 0xFC, 0xEC, 0x0A, 0xDA, 0x6F, 0x53, 0x62, 0xA3, 0x2E, 0x08, 0xAF,
Sergunb 0:8918a71cdbe9 223 0x28, 0xB0, 0x74, 0xC2, 0xBD, 0x36, 0x22, 0x38, 0x64, 0x1E, 0x39, 0x2C, 0xA6, 0x30, 0xE5, 0x44,
Sergunb 0:8918a71cdbe9 224 0xFD, 0x88, 0x9F, 0x65, 0x87, 0x6B, 0xF4, 0x23, 0x48, 0x10, 0xD1, 0x51, 0xC0, 0xF9, 0xD2, 0xA0,
Sergunb 0:8918a71cdbe9 225 0x55, 0xA1, 0x41, 0xFA, 0x43, 0x13, 0xC4, 0x2F, 0xA8, 0xB6, 0x3C, 0x2B, 0xC1, 0xFF, 0xC8, 0xA5,
Sergunb 0:8918a71cdbe9 226 0x20, 0x89, 0x00, 0x90, 0x47, 0xEF, 0xEA, 0xB7, 0x15, 0x06, 0xCD, 0xB5, 0x12, 0x7E, 0xBB, 0x29,
Sergunb 0:8918a71cdbe9 227 0x0F, 0xB8, 0x07, 0x04, 0x9B, 0x94, 0x21, 0x66, 0xE6, 0xCE, 0xED, 0xE7, 0x3B, 0xFE, 0x7F, 0xC5,
Sergunb 0:8918a71cdbe9 228 0xA4, 0x37, 0xB1, 0x4C, 0x91, 0x6E, 0x8D, 0x76, 0x03, 0x2D, 0xDE, 0x96, 0x26, 0x7D, 0xC6, 0x5C,
Sergunb 0:8918a71cdbe9 229 0xD3, 0xF2, 0x4F, 0x19, 0x3F, 0xDC, 0x79, 0x1D, 0x52, 0xEB, 0xF3, 0x6D, 0x5E, 0xFB, 0x69, 0xB2,
Sergunb 0:8918a71cdbe9 230 0xF0, 0x31, 0x0C, 0xD4, 0xCF, 0x8C, 0xE2, 0x75, 0xA9, 0x4A, 0x57, 0x84, 0x11, 0x45, 0x1B, 0xF5,
Sergunb 0:8918a71cdbe9 231 0xE4, 0x0E, 0x73, 0xAA, 0xF1, 0xDD, 0x59, 0x14, 0x6C, 0x92, 0x54, 0xD0, 0x78, 0x70, 0xE3, 0x49,
Sergunb 0:8918a71cdbe9 232 0x80, 0x50, 0xA7, 0xF6, 0x77, 0x93, 0x86, 0x83, 0x2A, 0xC7, 0x5B, 0xE9, 0xEE, 0x8F, 0x01, 0x3D
Sergunb 0:8918a71cdbe9 233 };
Sergunb 0:8918a71cdbe9 234
Sergunb 0:8918a71cdbe9 235 //Substitution table 3
Sergunb 0:8918a71cdbe9 236 static const uint8_t sbox3[256] =
Sergunb 0:8918a71cdbe9 237 {
Sergunb 0:8918a71cdbe9 238 0x38, 0x41, 0x16, 0x76, 0xD9, 0x93, 0x60, 0xF2, 0x72, 0xC2, 0xAB, 0x9A, 0x75, 0x06, 0x57, 0xA0,
Sergunb 0:8918a71cdbe9 239 0x91, 0xF7, 0xB5, 0xC9, 0xA2, 0x8C, 0xD2, 0x90, 0xF6, 0x07, 0xA7, 0x27, 0x8E, 0xB2, 0x49, 0xDE,
Sergunb 0:8918a71cdbe9 240 0x43, 0x5C, 0xD7, 0xC7, 0x3E, 0xF5, 0x8F, 0x67, 0x1F, 0x18, 0x6E, 0xAF, 0x2F, 0xE2, 0x85, 0x0D,
Sergunb 0:8918a71cdbe9 241 0x53, 0xF0, 0x9C, 0x65, 0xEA, 0xA3, 0xAE, 0x9E, 0xEC, 0x80, 0x2D, 0x6B, 0xA8, 0x2B, 0x36, 0xA6,
Sergunb 0:8918a71cdbe9 242 0xC5, 0x86, 0x4D, 0x33, 0xFD, 0x66, 0x58, 0x96, 0x3A, 0x09, 0x95, 0x10, 0x78, 0xD8, 0x42, 0xCC,
Sergunb 0:8918a71cdbe9 243 0xEF, 0x26, 0xE5, 0x61, 0x1A, 0x3F, 0x3B, 0x82, 0xB6, 0xDB, 0xD4, 0x98, 0xE8, 0x8B, 0x02, 0xEB,
Sergunb 0:8918a71cdbe9 244 0x0A, 0x2C, 0x1D, 0xB0, 0x6F, 0x8D, 0x88, 0x0E, 0x19, 0x87, 0x4E, 0x0B, 0xA9, 0x0C, 0x79, 0x11,
Sergunb 0:8918a71cdbe9 245 0x7F, 0x22, 0xE7, 0x59, 0xE1, 0xDA, 0x3D, 0xC8, 0x12, 0x04, 0x74, 0x54, 0x30, 0x7E, 0xB4, 0x28,
Sergunb 0:8918a71cdbe9 246 0x55, 0x68, 0x50, 0xBE, 0xD0, 0xC4, 0x31, 0xCB, 0x2A, 0xAD, 0x0F, 0xCA, 0x70, 0xFF, 0x32, 0x69,
Sergunb 0:8918a71cdbe9 247 0x08, 0x62, 0x00, 0x24, 0xD1, 0xFB, 0xBA, 0xED, 0x45, 0x81, 0x73, 0x6D, 0x84, 0x9F, 0xEE, 0x4A,
Sergunb 0:8918a71cdbe9 248 0xC3, 0x2E, 0xC1, 0x01, 0xE6, 0x25, 0x48, 0x99, 0xB9, 0xB3, 0x7B, 0xF9, 0xCE, 0xBF, 0xDF, 0x71,
Sergunb 0:8918a71cdbe9 249 0x29, 0xCD, 0x6C, 0x13, 0x64, 0x9B, 0x63, 0x9D, 0xC0, 0x4B, 0xB7, 0xA5, 0x89, 0x5F, 0xB1, 0x17,
Sergunb 0:8918a71cdbe9 250 0xF4, 0xBC, 0xD3, 0x46, 0xCF, 0x37, 0x5E, 0x47, 0x94, 0xFA, 0xFC, 0x5B, 0x97, 0xFE, 0x5A, 0xAC,
Sergunb 0:8918a71cdbe9 251 0x3C, 0x4C, 0x03, 0x35, 0xF3, 0x23, 0xB8, 0x5D, 0x6A, 0x92, 0xD5, 0x21, 0x44, 0x51, 0xC6, 0x7D,
Sergunb 0:8918a71cdbe9 252 0x39, 0x83, 0xDC, 0xAA, 0x7C, 0x77, 0x56, 0x05, 0x1B, 0xA4, 0x15, 0x34, 0x1E, 0x1C, 0xF8, 0x52,
Sergunb 0:8918a71cdbe9 253 0x20, 0x14, 0xE9, 0xBD, 0xDD, 0xE4, 0xA1, 0xE0, 0x8A, 0xF1, 0xD6, 0x7A, 0xBB, 0xE3, 0x40, 0x4F
Sergunb 0:8918a71cdbe9 254 };
Sergunb 0:8918a71cdbe9 255
Sergunb 0:8918a71cdbe9 256 //Substitution table 4
Sergunb 0:8918a71cdbe9 257 static const uint8_t sbox4[256] =
Sergunb 0:8918a71cdbe9 258 {
Sergunb 0:8918a71cdbe9 259 0x70, 0x2C, 0xB3, 0xC0, 0xE4, 0x57, 0xEA, 0xAE, 0x23, 0x6B, 0x45, 0xA5, 0xED, 0x4F, 0x1D, 0x92,
Sergunb 0:8918a71cdbe9 260 0x86, 0xAF, 0x7C, 0x1F, 0x3E, 0xDC, 0x5E, 0x0B, 0xA6, 0x39, 0xD5, 0x5D, 0xD9, 0x5A, 0x51, 0x6C,
Sergunb 0:8918a71cdbe9 261 0x8B, 0x9A, 0xFB, 0xB0, 0x74, 0x2B, 0xF0, 0x84, 0xDF, 0xCB, 0x34, 0x76, 0x6D, 0xA9, 0xD1, 0x04,
Sergunb 0:8918a71cdbe9 262 0x14, 0x3A, 0xDE, 0x11, 0x32, 0x9C, 0x53, 0xF2, 0xFE, 0xCF, 0xC3, 0x7A, 0x24, 0xE8, 0x60, 0x69,
Sergunb 0:8918a71cdbe9 263 0xAA, 0xA0, 0xA1, 0x62, 0x54, 0x1E, 0xE0, 0x64, 0x10, 0x00, 0xA3, 0x75, 0x8A, 0xE6, 0x09, 0xDD,
Sergunb 0:8918a71cdbe9 264 0x87, 0x83, 0xCD, 0x90, 0x73, 0xF6, 0x9D, 0xBF, 0x52, 0xD8, 0xC8, 0xC6, 0x81, 0x6F, 0x13, 0x63,
Sergunb 0:8918a71cdbe9 265 0xE9, 0xA7, 0x9F, 0xBC, 0x29, 0xF9, 0x2F, 0xB4, 0x78, 0x06, 0xE7, 0x71, 0xD4, 0xAB, 0x88, 0x8D,
Sergunb 0:8918a71cdbe9 266 0x72, 0xB9, 0xF8, 0xAC, 0x36, 0x2A, 0x3C, 0xF1, 0x40, 0xD3, 0xBB, 0x43, 0x15, 0xAD, 0x77, 0x80,
Sergunb 0:8918a71cdbe9 267 0x82, 0xEC, 0x27, 0xE5, 0x85, 0x35, 0x0C, 0x41, 0xEF, 0x93, 0x19, 0x21, 0x0E, 0x4E, 0x65, 0xBD,
Sergunb 0:8918a71cdbe9 268 0xB8, 0x8F, 0xEB, 0xCE, 0x30, 0x5F, 0xC5, 0x1A, 0xE1, 0xCA, 0x47, 0x3D, 0x01, 0xD6, 0x56, 0x4D,
Sergunb 0:8918a71cdbe9 269 0x0D, 0x66, 0xCC, 0x2D, 0x12, 0x20, 0xB1, 0x99, 0x4C, 0xC2, 0x7E, 0x05, 0xB7, 0x31, 0x17, 0xD7,
Sergunb 0:8918a71cdbe9 270 0x58, 0x61, 0x1B, 0x1C, 0x0F, 0x16, 0x18, 0x22, 0x44, 0xB2, 0xB5, 0x91, 0x08, 0xA8, 0xFC, 0x50,
Sergunb 0:8918a71cdbe9 271 0xD0, 0x7D, 0x89, 0x97, 0x5B, 0x95, 0xFF, 0xD2, 0xC4, 0x48, 0xF7, 0xDB, 0x03, 0xDA, 0x3F, 0x94,
Sergunb 0:8918a71cdbe9 272 0x5C, 0x02, 0x4A, 0x33, 0x67, 0xF3, 0x7F, 0xE2, 0x9B, 0x26, 0x37, 0x3B, 0x96, 0x4B, 0xBE, 0x2E,
Sergunb 0:8918a71cdbe9 273 0x79, 0x8C, 0x6E, 0x8E, 0xF5, 0xB6, 0xFD, 0x59, 0x98, 0x6A, 0x46, 0xBA, 0x25, 0x42, 0xA2, 0xFA,
Sergunb 0:8918a71cdbe9 274 0x07, 0x55, 0xEE, 0x0A, 0x49, 0x68, 0x38, 0xA4, 0x28, 0x7B, 0xC9, 0xC1, 0xE3, 0xF4, 0xC7, 0x9E
Sergunb 0:8918a71cdbe9 275 };
Sergunb 0:8918a71cdbe9 276
Sergunb 0:8918a71cdbe9 277 //Common interface for encryption algorithms
Sergunb 0:8918a71cdbe9 278 const CipherAlgo camelliaCipherAlgo =
Sergunb 0:8918a71cdbe9 279 {
Sergunb 0:8918a71cdbe9 280 "CAMELLIA",
Sergunb 0:8918a71cdbe9 281 sizeof(CamelliaContext),
Sergunb 0:8918a71cdbe9 282 CIPHER_ALGO_TYPE_BLOCK,
Sergunb 0:8918a71cdbe9 283 CAMELLIA_BLOCK_SIZE,
Sergunb 0:8918a71cdbe9 284 (CipherAlgoInit) camelliaInit,
Sergunb 0:8918a71cdbe9 285 NULL,
Sergunb 0:8918a71cdbe9 286 NULL,
Sergunb 0:8918a71cdbe9 287 (CipherAlgoEncryptBlock) camelliaEncryptBlock,
Sergunb 0:8918a71cdbe9 288 (CipherAlgoDecryptBlock) camelliaDecryptBlock
Sergunb 0:8918a71cdbe9 289 };
Sergunb 0:8918a71cdbe9 290
Sergunb 0:8918a71cdbe9 291
Sergunb 0:8918a71cdbe9 292 /**
Sergunb 0:8918a71cdbe9 293 * @brief Initialize a Camellia context using the supplied key
Sergunb 0:8918a71cdbe9 294 * @param[in] context Pointer to the Camellia context to initialize
Sergunb 0:8918a71cdbe9 295 * @param[in] key Pointer to the key
Sergunb 0:8918a71cdbe9 296 * @param[in] keyLength Length of the key
Sergunb 0:8918a71cdbe9 297 * @return Error code
Sergunb 0:8918a71cdbe9 298 **/
Sergunb 0:8918a71cdbe9 299
Sergunb 0:8918a71cdbe9 300 error_t camelliaInit(CamelliaContext *context, const uint8_t *key, size_t keyLength)
Sergunb 0:8918a71cdbe9 301 {
Sergunb 0:8918a71cdbe9 302 uint_t i;
Sergunb 0:8918a71cdbe9 303 uint32_t temp1;
Sergunb 0:8918a71cdbe9 304 uint32_t temp2;
Sergunb 0:8918a71cdbe9 305 uint32_t *k;
Sergunb 0:8918a71cdbe9 306 const CamelliaSubkey *p;
Sergunb 0:8918a71cdbe9 307
Sergunb 0:8918a71cdbe9 308 //18 rounds are required for 128-bit key
Sergunb 0:8918a71cdbe9 309 if(keyLength == 16)
Sergunb 0:8918a71cdbe9 310 context->nr = 18;
Sergunb 0:8918a71cdbe9 311 //24 rounds are required for 192 and 256-bit keys
Sergunb 0:8918a71cdbe9 312 else if(keyLength == 24 || keyLength == 32)
Sergunb 0:8918a71cdbe9 313 context->nr = 24;
Sergunb 0:8918a71cdbe9 314 //Key length is not supported...
Sergunb 0:8918a71cdbe9 315 else
Sergunb 0:8918a71cdbe9 316 return ERROR_INVALID_KEY_LENGTH;
Sergunb 0:8918a71cdbe9 317
Sergunb 0:8918a71cdbe9 318 //Point to KA, KB, KL and KR
Sergunb 0:8918a71cdbe9 319 k = context->k;
Sergunb 0:8918a71cdbe9 320 //Clear key contents
Sergunb 0:8918a71cdbe9 321 memset(k, 0, 64);
Sergunb 0:8918a71cdbe9 322 //Save the supplied secret key
Sergunb 0:8918a71cdbe9 323 memcpy(k, key, keyLength);
Sergunb 0:8918a71cdbe9 324
Sergunb 0:8918a71cdbe9 325 //192-bit keys require special processing
Sergunb 0:8918a71cdbe9 326 if(keyLength == 24)
Sergunb 0:8918a71cdbe9 327 {
Sergunb 0:8918a71cdbe9 328 //Form a 256-bit key
Sergunb 0:8918a71cdbe9 329 k[KR + 2] = ~k[KR + 0];
Sergunb 0:8918a71cdbe9 330 k[KR + 3] = ~k[KR + 1];
Sergunb 0:8918a71cdbe9 331 }
Sergunb 0:8918a71cdbe9 332
Sergunb 0:8918a71cdbe9 333 //XOR KL and KR before applying the rounds
Sergunb 0:8918a71cdbe9 334 for(i = 0; i < 4; i++)
Sergunb 0:8918a71cdbe9 335 {
Sergunb 0:8918a71cdbe9 336 k[KL + i] = betoh32(k[KL + i]);
Sergunb 0:8918a71cdbe9 337 k[KR + i] = betoh32(k[KR + i]);
Sergunb 0:8918a71cdbe9 338 k[KB + i] = k[KL + i] ^ k[KR + i];
Sergunb 0:8918a71cdbe9 339 }
Sergunb 0:8918a71cdbe9 340
Sergunb 0:8918a71cdbe9 341 //Generate the 128-bit keys KA and KB
Sergunb 0:8918a71cdbe9 342 for(i = 0; i < 6; i++)
Sergunb 0:8918a71cdbe9 343 {
Sergunb 0:8918a71cdbe9 344 //Apply round function
Sergunb 0:8918a71cdbe9 345 CAMELLIA_ROUND(k[KB + 0], k[KB + 1], k[KB + 2], k[KB + 3], sigma[2 * i], sigma[2 * i + 1]);
Sergunb 0:8918a71cdbe9 346
Sergunb 0:8918a71cdbe9 347 //The 2nd round requires special processing
Sergunb 0:8918a71cdbe9 348 if(i == 1)
Sergunb 0:8918a71cdbe9 349 {
Sergunb 0:8918a71cdbe9 350 //The result is XORed with KL
Sergunb 0:8918a71cdbe9 351 k[KB + 0] ^= k[KL + 0];
Sergunb 0:8918a71cdbe9 352 k[KB + 1] ^= k[KL + 1];
Sergunb 0:8918a71cdbe9 353 k[KB + 2] ^= k[KL + 2];
Sergunb 0:8918a71cdbe9 354 k[KB + 3] ^= k[KL + 3];
Sergunb 0:8918a71cdbe9 355 }
Sergunb 0:8918a71cdbe9 356 //The 4th round requires special processing
Sergunb 0:8918a71cdbe9 357 else if(i == 3)
Sergunb 0:8918a71cdbe9 358 {
Sergunb 0:8918a71cdbe9 359 //Save KA after the 4th round
Sergunb 0:8918a71cdbe9 360 memcpy(k + KA, k + KB, 16);
Sergunb 0:8918a71cdbe9 361 //The result is XORed with KR
Sergunb 0:8918a71cdbe9 362 k[KB + 0] ^= k[KR + 0];
Sergunb 0:8918a71cdbe9 363 k[KB + 1] ^= k[KR + 1];
Sergunb 0:8918a71cdbe9 364 k[KB + 2] ^= k[KR + 2];
Sergunb 0:8918a71cdbe9 365 k[KB + 3] ^= k[KR + 3];
Sergunb 0:8918a71cdbe9 366 }
Sergunb 0:8918a71cdbe9 367 }
Sergunb 0:8918a71cdbe9 368
Sergunb 0:8918a71cdbe9 369 //The key schedule depends on the length of key
Sergunb 0:8918a71cdbe9 370 if(keyLength == 16)
Sergunb 0:8918a71cdbe9 371 {
Sergunb 0:8918a71cdbe9 372 //Key schedule for 128-bit key
Sergunb 0:8918a71cdbe9 373 i = arraysize(ks1);
Sergunb 0:8918a71cdbe9 374 p = ks1;
Sergunb 0:8918a71cdbe9 375 }
Sergunb 0:8918a71cdbe9 376 else
Sergunb 0:8918a71cdbe9 377 {
Sergunb 0:8918a71cdbe9 378 //Key schedule for 192 and 256-bit keys
Sergunb 0:8918a71cdbe9 379 i = arraysize(ks2);
Sergunb 0:8918a71cdbe9 380 p = ks2;
Sergunb 0:8918a71cdbe9 381 }
Sergunb 0:8918a71cdbe9 382
Sergunb 0:8918a71cdbe9 383 //Generate subkeys
Sergunb 0:8918a71cdbe9 384 while(i > 0)
Sergunb 0:8918a71cdbe9 385 {
Sergunb 0:8918a71cdbe9 386 //Calculate the shift count
Sergunb 0:8918a71cdbe9 387 uint_t n = (p->shift + p->position) / 32;
Sergunb 0:8918a71cdbe9 388 uint_t m = (p->shift + p->position) % 32;
Sergunb 0:8918a71cdbe9 389 //Point to KL, KR, KA or KB
Sergunb 0:8918a71cdbe9 390 k = context->k + p->key;
Sergunb 0:8918a71cdbe9 391
Sergunb 0:8918a71cdbe9 392 //Generate the current subkey
Sergunb 0:8918a71cdbe9 393 if(m == 0)
Sergunb 0:8918a71cdbe9 394 {
Sergunb 0:8918a71cdbe9 395 context->ks[p->index] = k[n % 4];
Sergunb 0:8918a71cdbe9 396 context->ks[p->index + 1] = k[(n + 1) % 4];
Sergunb 0:8918a71cdbe9 397 }
Sergunb 0:8918a71cdbe9 398 else
Sergunb 0:8918a71cdbe9 399 {
Sergunb 0:8918a71cdbe9 400 context->ks[p->index] = (k[n % 4] << m) | (k[(n + 1) % 4] >> (32 - m));
Sergunb 0:8918a71cdbe9 401 context->ks[p->index + 1] = (k[(n + 1) % 4] << m) | (k[(n + 2) % 4] >> (32 - m));
Sergunb 0:8918a71cdbe9 402 }
Sergunb 0:8918a71cdbe9 403
Sergunb 0:8918a71cdbe9 404 //Next subkey
Sergunb 0:8918a71cdbe9 405 p++;
Sergunb 0:8918a71cdbe9 406 i--;
Sergunb 0:8918a71cdbe9 407 }
Sergunb 0:8918a71cdbe9 408
Sergunb 0:8918a71cdbe9 409 //No error to report
Sergunb 0:8918a71cdbe9 410 return NO_ERROR;
Sergunb 0:8918a71cdbe9 411 }
Sergunb 0:8918a71cdbe9 412
Sergunb 0:8918a71cdbe9 413
Sergunb 0:8918a71cdbe9 414 /**
Sergunb 0:8918a71cdbe9 415 * @brief Encrypt a 16-byte block using Camellia algorithm
Sergunb 0:8918a71cdbe9 416 * @param[in] context Pointer to the Camellia context
Sergunb 0:8918a71cdbe9 417 * @param[in] input Plaintext block to encrypt
Sergunb 0:8918a71cdbe9 418 * @param[out] output Ciphertext block resulting from encryption
Sergunb 0:8918a71cdbe9 419 **/
Sergunb 0:8918a71cdbe9 420
Sergunb 0:8918a71cdbe9 421 void camelliaEncryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
Sergunb 0:8918a71cdbe9 422 {
Sergunb 0:8918a71cdbe9 423 uint_t i;
Sergunb 0:8918a71cdbe9 424 uint32_t temp1;
Sergunb 0:8918a71cdbe9 425 uint32_t temp2;
Sergunb 0:8918a71cdbe9 426 uint32_t *ks;
Sergunb 0:8918a71cdbe9 427
Sergunb 0:8918a71cdbe9 428 //The plaintext is separated into two parts (L and R)
Sergunb 0:8918a71cdbe9 429 uint32_t left1 = LOAD32BE(input + 0);
Sergunb 0:8918a71cdbe9 430 uint32_t left2 = LOAD32BE(input + 4);
Sergunb 0:8918a71cdbe9 431 uint32_t right1 = LOAD32BE(input + 8);
Sergunb 0:8918a71cdbe9 432 uint32_t right2 = LOAD32BE(input + 12);
Sergunb 0:8918a71cdbe9 433
Sergunb 0:8918a71cdbe9 434 //The key schedule must be applied in ascending order
Sergunb 0:8918a71cdbe9 435 ks = context->ks;
Sergunb 0:8918a71cdbe9 436
Sergunb 0:8918a71cdbe9 437 //XOR plaintext with kw1 and kw2
Sergunb 0:8918a71cdbe9 438 left1 ^= ks[0];
Sergunb 0:8918a71cdbe9 439 left2 ^= ks[1];
Sergunb 0:8918a71cdbe9 440 right1 ^= ks[2];
Sergunb 0:8918a71cdbe9 441 right2 ^= ks[3];
Sergunb 0:8918a71cdbe9 442 //Advance current location in key schedule
Sergunb 0:8918a71cdbe9 443 ks += 4;
Sergunb 0:8918a71cdbe9 444
Sergunb 0:8918a71cdbe9 445 //Apply round function 18 or 24 times depending on the key length
Sergunb 0:8918a71cdbe9 446 for(i = context->nr; i > 0; i--)
Sergunb 0:8918a71cdbe9 447 {
Sergunb 0:8918a71cdbe9 448 //Apply round function
Sergunb 0:8918a71cdbe9 449 CAMELLIA_ROUND(left1, left2, right1, right2, ks[0], ks[1]);
Sergunb 0:8918a71cdbe9 450 //Advance current location in key schedule
Sergunb 0:8918a71cdbe9 451 ks += 2;
Sergunb 0:8918a71cdbe9 452
Sergunb 0:8918a71cdbe9 453 //6th, 12th and 18th rounds require special processing
Sergunb 0:8918a71cdbe9 454 if(i == 7 || i == 13 || i == 19)
Sergunb 0:8918a71cdbe9 455 {
Sergunb 0:8918a71cdbe9 456 //Apply FL-function
Sergunb 0:8918a71cdbe9 457 CAMELLIA_FL(left1, left2, ks[0], ks[1])
Sergunb 0:8918a71cdbe9 458 //Apply inverse FL-function
Sergunb 0:8918a71cdbe9 459 CAMELLIA_INV_FL(right1, right2, ks[2], ks[3])
Sergunb 0:8918a71cdbe9 460 //Advance current location in key schedule
Sergunb 0:8918a71cdbe9 461 ks += 4;
Sergunb 0:8918a71cdbe9 462 }
Sergunb 0:8918a71cdbe9 463 }
Sergunb 0:8918a71cdbe9 464
Sergunb 0:8918a71cdbe9 465 //XOR operation with kw3 and kw4
Sergunb 0:8918a71cdbe9 466 right1 ^= ks[0];
Sergunb 0:8918a71cdbe9 467 right2 ^= ks[1];
Sergunb 0:8918a71cdbe9 468 left1 ^= ks[2];
Sergunb 0:8918a71cdbe9 469 left2 ^= ks[3];
Sergunb 0:8918a71cdbe9 470
Sergunb 0:8918a71cdbe9 471 //The resulting value is the ciphertext
Sergunb 0:8918a71cdbe9 472 STORE32BE(right1, output + 0);
Sergunb 0:8918a71cdbe9 473 STORE32BE(right2, output + 4);
Sergunb 0:8918a71cdbe9 474 STORE32BE(left1, output + 8);
Sergunb 0:8918a71cdbe9 475 STORE32BE(left2, output + 12);
Sergunb 0:8918a71cdbe9 476 }
Sergunb 0:8918a71cdbe9 477
Sergunb 0:8918a71cdbe9 478
Sergunb 0:8918a71cdbe9 479 /**
Sergunb 0:8918a71cdbe9 480 * @brief Decrypt a 16-byte block using Camellia algorithm
Sergunb 0:8918a71cdbe9 481 * @param[in] context Pointer to the Camellia context
Sergunb 0:8918a71cdbe9 482 * @param[in] input Ciphertext block to decrypt
Sergunb 0:8918a71cdbe9 483 * @param[out] output Plaintext block resulting from decryption
Sergunb 0:8918a71cdbe9 484 **/
Sergunb 0:8918a71cdbe9 485
Sergunb 0:8918a71cdbe9 486 void camelliaDecryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
Sergunb 0:8918a71cdbe9 487 {
Sergunb 0:8918a71cdbe9 488 uint_t i;
Sergunb 0:8918a71cdbe9 489 uint32_t temp1;
Sergunb 0:8918a71cdbe9 490 uint32_t temp2;
Sergunb 0:8918a71cdbe9 491 uint32_t *ks;
Sergunb 0:8918a71cdbe9 492
Sergunb 0:8918a71cdbe9 493 //The ciphertext is separated into two parts (L and R)
Sergunb 0:8918a71cdbe9 494 uint32_t right1 = LOAD32BE(input + 0);
Sergunb 0:8918a71cdbe9 495 uint32_t right2 = LOAD32BE(input + 4);
Sergunb 0:8918a71cdbe9 496 uint32_t left1 = LOAD32BE(input + 8);
Sergunb 0:8918a71cdbe9 497 uint32_t left2 = LOAD32BE(input + 12);
Sergunb 0:8918a71cdbe9 498
Sergunb 0:8918a71cdbe9 499 //The key schedule must be applied in reverse order
Sergunb 0:8918a71cdbe9 500 ks = (context->nr == 18) ? (context->ks + 48) : (context->ks + 64);
Sergunb 0:8918a71cdbe9 501
Sergunb 0:8918a71cdbe9 502 //XOR ciphertext with kw3 and kw4
Sergunb 0:8918a71cdbe9 503 right1 ^= ks[0];
Sergunb 0:8918a71cdbe9 504 right2 ^= ks[1];
Sergunb 0:8918a71cdbe9 505 left1 ^= ks[2];
Sergunb 0:8918a71cdbe9 506 left2 ^= ks[3];
Sergunb 0:8918a71cdbe9 507
Sergunb 0:8918a71cdbe9 508 //Apply round function 18 or 24 times depending on the key length
Sergunb 0:8918a71cdbe9 509 for(i = context->nr; i > 0; i--)
Sergunb 0:8918a71cdbe9 510 {
Sergunb 0:8918a71cdbe9 511 //Update current location in key schedule
Sergunb 0:8918a71cdbe9 512 ks -= 2;
Sergunb 0:8918a71cdbe9 513 //Apply round function
Sergunb 0:8918a71cdbe9 514 CAMELLIA_ROUND(right1, right2, left1, left2, ks[0], ks[1]);
Sergunb 0:8918a71cdbe9 515
Sergunb 0:8918a71cdbe9 516 //6th, 12th and 18th rounds require special processing
Sergunb 0:8918a71cdbe9 517 if(i == 7 || i == 13 || i == 19)
Sergunb 0:8918a71cdbe9 518 {
Sergunb 0:8918a71cdbe9 519 //Update current location in key schedule
Sergunb 0:8918a71cdbe9 520 ks -= 4;
Sergunb 0:8918a71cdbe9 521 //Apply FL-function
Sergunb 0:8918a71cdbe9 522 CAMELLIA_FL(right1, right2, ks[2], ks[3])
Sergunb 0:8918a71cdbe9 523 //Apply inverse FL-function
Sergunb 0:8918a71cdbe9 524 CAMELLIA_INV_FL(left1, left2, ks[0], ks[1])
Sergunb 0:8918a71cdbe9 525 }
Sergunb 0:8918a71cdbe9 526 }
Sergunb 0:8918a71cdbe9 527
Sergunb 0:8918a71cdbe9 528 //Update current location in key schedule
Sergunb 0:8918a71cdbe9 529 ks -= 4;
Sergunb 0:8918a71cdbe9 530 //XOR operation with kw1 and kw2
Sergunb 0:8918a71cdbe9 531 left1 ^= ks[0];
Sergunb 0:8918a71cdbe9 532 left2 ^= ks[1];
Sergunb 0:8918a71cdbe9 533 right1 ^= ks[2];
Sergunb 0:8918a71cdbe9 534 right2 ^= ks[3];
Sergunb 0:8918a71cdbe9 535
Sergunb 0:8918a71cdbe9 536 //The resulting value is the plaintext
Sergunb 0:8918a71cdbe9 537 STORE32BE(left1, output + 0);
Sergunb 0:8918a71cdbe9 538 STORE32BE(left2, output + 4);
Sergunb 0:8918a71cdbe9 539 STORE32BE(right1, output + 8);
Sergunb 0:8918a71cdbe9 540 STORE32BE(right2, output + 12);
Sergunb 0:8918a71cdbe9 541 }
Sergunb 0:8918a71cdbe9 542
Sergunb 0:8918a71cdbe9 543 #endif
Sergunb 0:8918a71cdbe9 544