Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers camellia.c Source File

camellia.c

Go to the documentation of this file.
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