xref: /optee_os/lib/libmbedtls/mbedtls/library/camellia.c (revision b0563631928755fe864b97785160fb3088e9efdc)
1817466cbSJens Wiklander /*
2817466cbSJens Wiklander  *  Camellia implementation
3817466cbSJens Wiklander  *
47901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
5*b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6817466cbSJens Wiklander  */
7817466cbSJens Wiklander /*
8817466cbSJens Wiklander  *  The Camellia block cipher was designed by NTT and Mitsubishi Electric
9817466cbSJens Wiklander  *  Corporation.
10817466cbSJens Wiklander  *
11817466cbSJens Wiklander  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
12817466cbSJens Wiklander  */
13817466cbSJens Wiklander 
147901324dSJerome Forissier #include "common.h"
15817466cbSJens Wiklander 
16817466cbSJens Wiklander #if defined(MBEDTLS_CAMELLIA_C)
17817466cbSJens Wiklander 
18817466cbSJens Wiklander #include "mbedtls/camellia.h"
193d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
20817466cbSJens Wiklander 
21817466cbSJens Wiklander #include <string.h>
22817466cbSJens Wiklander 
23817466cbSJens Wiklander #include "mbedtls/platform.h"
24817466cbSJens Wiklander 
25817466cbSJens Wiklander #if !defined(MBEDTLS_CAMELLIA_ALT)
26817466cbSJens Wiklander 
27817466cbSJens Wiklander static const unsigned char SIGMA_CHARS[6][8] =
28817466cbSJens Wiklander {
29817466cbSJens Wiklander     { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
30817466cbSJens Wiklander     { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
31817466cbSJens Wiklander     { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
32817466cbSJens Wiklander     { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
33817466cbSJens Wiklander     { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
34817466cbSJens Wiklander     { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
35817466cbSJens Wiklander };
36817466cbSJens Wiklander 
37817466cbSJens Wiklander #if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
38817466cbSJens Wiklander 
39817466cbSJens Wiklander static const unsigned char FSb[256] =
40817466cbSJens Wiklander {
41817466cbSJens Wiklander     112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
42817466cbSJens Wiklander     35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
43817466cbSJens Wiklander     134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
44817466cbSJens Wiklander     166, 225, 57, 202, 213, 71, 93, 61, 217,  1, 90, 214, 81, 86, 108, 77,
45817466cbSJens Wiklander     139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
46817466cbSJens Wiklander     223, 76, 203, 194, 52, 126, 118,  5, 109, 183, 169, 49, 209, 23,  4, 215,
47817466cbSJens Wiklander     20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
48817466cbSJens Wiklander     254, 68, 207, 178, 195, 181, 122, 145, 36,  8, 232, 168, 96, 252, 105, 80,
49817466cbSJens Wiklander     170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
50817466cbSJens Wiklander     16, 196,  0, 72, 163, 247, 117, 219, 138,  3, 230, 218,  9, 63, 221, 148,
51817466cbSJens Wiklander     135, 92, 131,  2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
52817466cbSJens Wiklander     82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
53817466cbSJens Wiklander     233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
54817466cbSJens Wiklander     120, 152,  6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
55817466cbSJens Wiklander     114,  7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
56817466cbSJens Wiklander     64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
57817466cbSJens Wiklander };
58817466cbSJens Wiklander 
59817466cbSJens Wiklander #define SBOX1(n) FSb[(n)]
60817466cbSJens Wiklander #define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
61817466cbSJens Wiklander #define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
62817466cbSJens Wiklander #define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
63817466cbSJens Wiklander 
64817466cbSJens Wiklander #else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
65817466cbSJens Wiklander 
66817466cbSJens Wiklander static const unsigned char FSb[256] =
67817466cbSJens Wiklander {
68817466cbSJens Wiklander     112, 130,  44, 236, 179,  39, 192, 229, 228, 133,  87,  53, 234,  12, 174,  65,
69817466cbSJens Wiklander     35, 239, 107, 147,  69,  25, 165,  33, 237,  14,  79,  78,  29, 101, 146, 189,
70817466cbSJens Wiklander     134, 184, 175, 143, 124, 235,  31, 206,  62,  48, 220,  95,  94, 197,  11,  26,
71817466cbSJens Wiklander     166, 225,  57, 202, 213,  71,  93,  61, 217,   1,  90, 214,  81,  86, 108,  77,
72817466cbSJens Wiklander     139,  13, 154, 102, 251, 204, 176,  45, 116,  18,  43,  32, 240, 177, 132, 153,
73817466cbSJens Wiklander     223,  76, 203, 194,  52, 126, 118,   5, 109, 183, 169,  49, 209,  23,   4, 215,
74817466cbSJens Wiklander     20,  88,  58,  97, 222,  27,  17,  28,  50,  15, 156,  22,  83,  24, 242,  34,
75817466cbSJens Wiklander     254,  68, 207, 178, 195, 181, 122, 145,  36,   8, 232, 168,  96, 252, 105,  80,
76817466cbSJens Wiklander     170, 208, 160, 125, 161, 137,  98, 151,  84,  91,  30, 149, 224, 255, 100, 210,
77817466cbSJens Wiklander     16, 196,   0,  72, 163, 247, 117, 219, 138,   3, 230, 218,   9,  63, 221, 148,
78817466cbSJens Wiklander     135,  92, 131,   2, 205,  74, 144,  51, 115, 103, 246, 243, 157, 127, 191, 226,
79817466cbSJens Wiklander     82, 155, 216,  38, 200,  55, 198,  59, 129, 150, 111,  75,  19, 190,  99,  46,
80817466cbSJens Wiklander     233, 121, 167, 140, 159, 110, 188, 142,  41, 245, 249, 182,  47, 253, 180,  89,
81817466cbSJens Wiklander     120, 152,   6, 106, 231,  70, 113, 186, 212,  37, 171,  66, 136, 162, 141, 250,
82817466cbSJens Wiklander     114,   7, 185,  85, 248, 238, 172,  10,  54,  73,  42, 104,  60,  56, 241, 164,
83817466cbSJens Wiklander     64,  40, 211, 123, 187, 201,  67, 193,  21, 227, 173, 244, 119, 199, 128, 158
84817466cbSJens Wiklander };
85817466cbSJens Wiklander 
86817466cbSJens Wiklander static const unsigned char FSb2[256] =
87817466cbSJens Wiklander {
88817466cbSJens Wiklander     224,   5,  88, 217, 103,  78, 129, 203, 201,  11, 174, 106, 213,  24,  93, 130,
89817466cbSJens Wiklander     70, 223, 214,  39, 138,  50,  75,  66, 219,  28, 158, 156,  58, 202,  37, 123,
90817466cbSJens Wiklander     13, 113,  95,  31, 248, 215,  62, 157, 124,  96, 185, 190, 188, 139,  22,  52,
91817466cbSJens Wiklander     77, 195, 114, 149, 171, 142, 186, 122, 179,   2, 180, 173, 162, 172, 216, 154,
92817466cbSJens Wiklander     23,  26,  53, 204, 247, 153,  97,  90, 232,  36,  86,  64, 225,  99,   9,  51,
93817466cbSJens Wiklander     191, 152, 151, 133, 104, 252, 236,  10, 218, 111,  83,  98, 163,  46,   8, 175,
94817466cbSJens Wiklander     40, 176, 116, 194, 189,  54,  34,  56, 100,  30,  57,  44, 166,  48, 229,  68,
95817466cbSJens Wiklander     253, 136, 159, 101, 135, 107, 244,  35,  72,  16, 209,  81, 192, 249, 210, 160,
96817466cbSJens Wiklander     85, 161,  65, 250,  67,  19, 196,  47, 168, 182,  60,  43, 193, 255, 200, 165,
97817466cbSJens Wiklander     32, 137,   0, 144,  71, 239, 234, 183,  21,   6, 205, 181,  18, 126, 187,  41,
98817466cbSJens Wiklander     15, 184,   7,   4, 155, 148,  33, 102, 230, 206, 237, 231,  59, 254, 127, 197,
99817466cbSJens Wiklander     164,  55, 177,  76, 145, 110, 141, 118,   3,  45, 222, 150,  38, 125, 198,  92,
100817466cbSJens Wiklander     211, 242,  79,  25,  63, 220, 121,  29,  82, 235, 243, 109,  94, 251, 105, 178,
101817466cbSJens Wiklander     240,  49,  12, 212, 207, 140, 226, 117, 169,  74,  87, 132,  17,  69,  27, 245,
102817466cbSJens Wiklander     228,  14, 115, 170, 241, 221,  89,  20, 108, 146,  84, 208, 120, 112, 227,  73,
103817466cbSJens Wiklander     128,  80, 167, 246, 119, 147, 134, 131,  42, 199,  91, 233, 238, 143,   1,  61
104817466cbSJens Wiklander };
105817466cbSJens Wiklander 
106817466cbSJens Wiklander static const unsigned char FSb3[256] =
107817466cbSJens Wiklander {
108817466cbSJens Wiklander     56,  65,  22, 118, 217, 147,  96, 242, 114, 194, 171, 154, 117,   6,  87, 160,
109817466cbSJens Wiklander     145, 247, 181, 201, 162, 140, 210, 144, 246,   7, 167,  39, 142, 178,  73, 222,
110817466cbSJens Wiklander     67,  92, 215, 199,  62, 245, 143, 103,  31,  24, 110, 175,  47, 226, 133,  13,
111817466cbSJens Wiklander     83, 240, 156, 101, 234, 163, 174, 158, 236, 128,  45, 107, 168,  43,  54, 166,
112817466cbSJens Wiklander     197, 134,  77,  51, 253, 102,  88, 150,  58,   9, 149,  16, 120, 216,  66, 204,
113817466cbSJens Wiklander     239,  38, 229,  97,  26,  63,  59, 130, 182, 219, 212, 152, 232, 139,   2, 235,
114817466cbSJens Wiklander     10,  44,  29, 176, 111, 141, 136,  14,  25, 135,  78,  11, 169,  12, 121,  17,
115817466cbSJens Wiklander     127,  34, 231,  89, 225, 218,  61, 200,  18,   4, 116,  84,  48, 126, 180,  40,
116817466cbSJens Wiklander     85, 104,  80, 190, 208, 196,  49, 203,  42, 173,  15, 202, 112, 255,  50, 105,
117817466cbSJens Wiklander     8,  98,   0,  36, 209, 251, 186, 237,  69, 129, 115, 109, 132, 159, 238,  74,
118817466cbSJens Wiklander     195,  46, 193,   1, 230,  37,  72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
119817466cbSJens Wiklander     41, 205, 108,  19, 100, 155,  99, 157, 192,  75, 183, 165, 137,  95, 177,  23,
120817466cbSJens Wiklander     244, 188, 211,  70, 207,  55,  94,  71, 148, 250, 252,  91, 151, 254,  90, 172,
121817466cbSJens Wiklander     60,  76,   3,  53, 243,  35, 184,  93, 106, 146, 213,  33,  68,  81, 198, 125,
122817466cbSJens Wiklander     57, 131, 220, 170, 124, 119,  86,   5,  27, 164,  21,  52,  30,  28, 248,  82,
123817466cbSJens Wiklander     32,  20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227,  64,  79
124817466cbSJens Wiklander };
125817466cbSJens Wiklander 
126817466cbSJens Wiklander static const unsigned char FSb4[256] =
127817466cbSJens Wiklander {
128817466cbSJens Wiklander     112,  44, 179, 192, 228,  87, 234, 174,  35, 107,  69, 165, 237,  79,  29, 146,
129817466cbSJens Wiklander     134, 175, 124,  31,  62, 220,  94,  11, 166,  57, 213,  93, 217,  90,  81, 108,
130817466cbSJens Wiklander     139, 154, 251, 176, 116,  43, 240, 132, 223, 203,  52, 118, 109, 169, 209,   4,
131817466cbSJens Wiklander     20,  58, 222,  17,  50, 156,  83, 242, 254, 207, 195, 122,  36, 232,  96, 105,
132817466cbSJens Wiklander     170, 160, 161,  98,  84,  30, 224, 100,  16,   0, 163, 117, 138, 230,   9, 221,
133817466cbSJens Wiklander     135, 131, 205, 144, 115, 246, 157, 191,  82, 216, 200, 198, 129, 111,  19,  99,
134817466cbSJens Wiklander     233, 167, 159, 188,  41, 249,  47, 180, 120,   6, 231, 113, 212, 171, 136, 141,
135817466cbSJens Wiklander     114, 185, 248, 172,  54,  42,  60, 241,  64, 211, 187,  67,  21, 173, 119, 128,
136817466cbSJens Wiklander     130, 236,  39, 229, 133,  53,  12,  65, 239, 147,  25,  33,  14,  78, 101, 189,
137817466cbSJens Wiklander     184, 143, 235, 206,  48,  95, 197,  26, 225, 202,  71,  61,   1, 214,  86,  77,
138817466cbSJens Wiklander     13, 102, 204,  45,  18,  32, 177, 153,  76, 194, 126,   5, 183,  49,  23, 215,
139817466cbSJens Wiklander     88,  97,  27,  28,  15,  22,  24,  34,  68, 178, 181, 145,   8, 168, 252,  80,
140817466cbSJens Wiklander     208, 125, 137, 151,  91, 149, 255, 210, 196,  72, 247, 219,   3, 218,  63, 148,
141817466cbSJens Wiklander     92,   2,  74,  51, 103, 243, 127, 226, 155,  38,  55,  59, 150,  75, 190,  46,
142817466cbSJens Wiklander     121, 140, 110, 142, 245, 182, 253,  89, 152, 106,  70, 186,  37,  66, 162, 250,
143817466cbSJens Wiklander     7,  85, 238,  10,  73, 104,  56, 164,  40, 123, 201, 193, 227, 244, 199, 158
144817466cbSJens Wiklander };
145817466cbSJens Wiklander 
146817466cbSJens Wiklander #define SBOX1(n) FSb[(n)]
147817466cbSJens Wiklander #define SBOX2(n) FSb2[(n)]
148817466cbSJens Wiklander #define SBOX3(n) FSb3[(n)]
149817466cbSJens Wiklander #define SBOX4(n) FSb4[(n)]
150817466cbSJens Wiklander 
151817466cbSJens Wiklander #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
152817466cbSJens Wiklander 
153817466cbSJens Wiklander static const unsigned char shifts[2][4][4] =
154817466cbSJens Wiklander {
155817466cbSJens Wiklander     {
156817466cbSJens Wiklander         { 1, 1, 1, 1 }, /* KL */
157817466cbSJens Wiklander         { 0, 0, 0, 0 }, /* KR */
158817466cbSJens Wiklander         { 1, 1, 1, 1 }, /* KA */
159817466cbSJens Wiklander         { 0, 0, 0, 0 }  /* KB */
160817466cbSJens Wiklander     },
161817466cbSJens Wiklander     {
162817466cbSJens Wiklander         { 1, 0, 1, 1 }, /* KL */
163817466cbSJens Wiklander         { 1, 1, 0, 1 }, /* KR */
164817466cbSJens Wiklander         { 1, 1, 1, 0 }, /* KA */
165817466cbSJens Wiklander         { 1, 1, 0, 1 }  /* KB */
166817466cbSJens Wiklander     }
167817466cbSJens Wiklander };
168817466cbSJens Wiklander 
169817466cbSJens Wiklander static const signed char indexes[2][4][20] =
170817466cbSJens Wiklander {
171817466cbSJens Wiklander     {
172817466cbSJens Wiklander         {  0,  1,  2,  3,  8,  9, 10, 11, 38, 39,
173817466cbSJens Wiklander            36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
174817466cbSJens Wiklander         { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
175817466cbSJens Wiklander           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
176817466cbSJens Wiklander         {  4,  5,  6,  7, 12, 13, 14, 15, 16, 17,
177817466cbSJens Wiklander            18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
178817466cbSJens Wiklander         { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
179817466cbSJens Wiklander           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }  /* KB -> RK */
180817466cbSJens Wiklander     },
181817466cbSJens Wiklander     {
182817466cbSJens Wiklander         {  0,  1,  2,  3, 61, 62, 63, 60, -1, -1,
183817466cbSJens Wiklander            -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
184817466cbSJens Wiklander         { -1, -1, -1, -1,  8,  9, 10, 11, 16, 17,
185817466cbSJens Wiklander           18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
186817466cbSJens Wiklander         { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
187817466cbSJens Wiklander           56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
188817466cbSJens Wiklander         {  4,  5,  6,  7, 65, 66, 67, 64, 20, 21,
189817466cbSJens Wiklander            22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
190817466cbSJens Wiklander     }
191817466cbSJens Wiklander };
192817466cbSJens Wiklander 
193817466cbSJens Wiklander static const signed char transposes[2][20] =
194817466cbSJens Wiklander {
195817466cbSJens Wiklander     {
196817466cbSJens Wiklander         21, 22, 23, 20,
197817466cbSJens Wiklander         -1, -1, -1, -1,
198817466cbSJens Wiklander         18, 19, 16, 17,
199817466cbSJens Wiklander         11,  8,  9, 10,
200817466cbSJens Wiklander         15, 12, 13, 14
201817466cbSJens Wiklander     },
202817466cbSJens Wiklander     {
203817466cbSJens Wiklander         25, 26, 27, 24,
204817466cbSJens Wiklander         29, 30, 31, 28,
205817466cbSJens Wiklander         18, 19, 16, 17,
206817466cbSJens Wiklander         -1, -1, -1, -1,
207817466cbSJens Wiklander         -1, -1, -1, -1
208817466cbSJens Wiklander     }
209817466cbSJens Wiklander };
210817466cbSJens Wiklander 
211817466cbSJens Wiklander /* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
212817466cbSJens Wiklander #define ROTL(DEST, SRC, SHIFT)                                      \
213817466cbSJens Wiklander     {                                                                   \
214817466cbSJens Wiklander         (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT));   \
215817466cbSJens Wiklander         (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT));   \
216817466cbSJens Wiklander         (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT));   \
217817466cbSJens Wiklander         (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT));   \
218817466cbSJens Wiklander     }
219817466cbSJens Wiklander 
220817466cbSJens Wiklander #define FL(XL, XR, KL, KR)                                          \
221817466cbSJens Wiklander     {                                                                   \
222817466cbSJens Wiklander         (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR);   \
223817466cbSJens Wiklander         (XL) = ((XR) | (KR)) ^ (XL);                                    \
224817466cbSJens Wiklander     }
225817466cbSJens Wiklander 
226817466cbSJens Wiklander #define FLInv(YL, YR, KL, KR)                                       \
227817466cbSJens Wiklander     {                                                                   \
228817466cbSJens Wiklander         (YL) = ((YR) | (KR)) ^ (YL);                                    \
229817466cbSJens Wiklander         (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR);   \
230817466cbSJens Wiklander     }
231817466cbSJens Wiklander 
232817466cbSJens Wiklander #define SHIFT_AND_PLACE(INDEX, OFFSET)                      \
233817466cbSJens Wiklander     {                                                           \
234817466cbSJens Wiklander         TK[0] = KC[(OFFSET) * 4 + 0];                           \
235817466cbSJens Wiklander         TK[1] = KC[(OFFSET) * 4 + 1];                           \
236817466cbSJens Wiklander         TK[2] = KC[(OFFSET) * 4 + 2];                           \
237817466cbSJens Wiklander         TK[3] = KC[(OFFSET) * 4 + 3];                           \
238817466cbSJens Wiklander                                                             \
239817466cbSJens Wiklander         for (i = 1; i <= 4; i++)                               \
240817466cbSJens Wiklander         if (shifts[(INDEX)][(OFFSET)][i -1])               \
241817466cbSJens Wiklander         ROTL(TK + i * 4, TK, (15 * i) % 32);          \
242817466cbSJens Wiklander                                                             \
243817466cbSJens Wiklander         for (i = 0; i < 20; i++)                               \
244817466cbSJens Wiklander         if (indexes[(INDEX)][(OFFSET)][i] != -1) {         \
245817466cbSJens Wiklander             RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i];    \
246817466cbSJens Wiklander         }                                                   \
247817466cbSJens Wiklander     }
248817466cbSJens Wiklander 
camellia_feistel(const uint32_t x[2],const uint32_t k[2],uint32_t z[2])249817466cbSJens Wiklander static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
250817466cbSJens Wiklander                              uint32_t z[2])
251817466cbSJens Wiklander {
252817466cbSJens Wiklander     uint32_t I0, I1;
253817466cbSJens Wiklander     I0 = x[0] ^ k[0];
254817466cbSJens Wiklander     I1 = x[1] ^ k[1];
255817466cbSJens Wiklander 
256039e02dfSJerome Forissier     I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
257039e02dfSJerome Forissier          ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
258039e02dfSJerome Forissier          ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) <<  8) |
259039e02dfSJerome Forissier          ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
260039e02dfSJerome Forissier     I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
261039e02dfSJerome Forissier          ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
262039e02dfSJerome Forissier          ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) <<  8) |
263039e02dfSJerome Forissier          ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
264817466cbSJens Wiklander 
265817466cbSJens Wiklander     I0 ^= (I1 << 8) | (I1 >> 24);
266817466cbSJens Wiklander     I1 ^= (I0 << 16) | (I0 >> 16);
267817466cbSJens Wiklander     I0 ^= (I1 >> 8) | (I1 << 24);
268817466cbSJens Wiklander     I1 ^= (I0 >> 8) | (I0 << 24);
269817466cbSJens Wiklander 
270817466cbSJens Wiklander     z[0] ^= I1;
271817466cbSJens Wiklander     z[1] ^= I0;
272817466cbSJens Wiklander }
273817466cbSJens Wiklander 
mbedtls_camellia_init(mbedtls_camellia_context * ctx)274817466cbSJens Wiklander void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
275817466cbSJens Wiklander {
276817466cbSJens Wiklander     memset(ctx, 0, sizeof(mbedtls_camellia_context));
277817466cbSJens Wiklander }
278817466cbSJens Wiklander 
mbedtls_camellia_free(mbedtls_camellia_context * ctx)279817466cbSJens Wiklander void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
280817466cbSJens Wiklander {
28132b31808SJens Wiklander     if (ctx == NULL) {
282817466cbSJens Wiklander         return;
28332b31808SJens Wiklander     }
284817466cbSJens Wiklander 
2853d3b0591SJens Wiklander     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
286817466cbSJens Wiklander }
287817466cbSJens Wiklander 
288817466cbSJens Wiklander /*
289817466cbSJens Wiklander  * Camellia key schedule (encryption)
290817466cbSJens Wiklander  */
mbedtls_camellia_setkey_enc(mbedtls_camellia_context * ctx,const unsigned char * key,unsigned int keybits)2913d3b0591SJens Wiklander int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
2923d3b0591SJens Wiklander                                 const unsigned char *key,
293817466cbSJens Wiklander                                 unsigned int keybits)
294817466cbSJens Wiklander {
295817466cbSJens Wiklander     int idx;
296817466cbSJens Wiklander     size_t i;
297817466cbSJens Wiklander     uint32_t *RK;
298817466cbSJens Wiklander     unsigned char t[64];
299817466cbSJens Wiklander     uint32_t SIGMA[6][2];
300817466cbSJens Wiklander     uint32_t KC[16];
301817466cbSJens Wiklander     uint32_t TK[20];
302817466cbSJens Wiklander 
303817466cbSJens Wiklander     RK = ctx->rk;
304817466cbSJens Wiklander 
305817466cbSJens Wiklander     memset(t, 0, 64);
306817466cbSJens Wiklander     memset(RK, 0, sizeof(ctx->rk));
307817466cbSJens Wiklander 
30832b31808SJens Wiklander     switch (keybits) {
309817466cbSJens Wiklander         case 128: ctx->nr = 3; idx = 0; break;
310817466cbSJens Wiklander         case 192:
311817466cbSJens Wiklander         case 256: ctx->nr = 4; idx = 1; break;
31232b31808SJens Wiklander         default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
313817466cbSJens Wiklander     }
314817466cbSJens Wiklander 
31532b31808SJens Wiklander     for (i = 0; i < keybits / 8; ++i) {
316817466cbSJens Wiklander         t[i] = key[i];
31732b31808SJens Wiklander     }
318817466cbSJens Wiklander 
319817466cbSJens Wiklander     if (keybits == 192) {
32032b31808SJens Wiklander         for (i = 0; i < 8; i++) {
321817466cbSJens Wiklander             t[24 + i] = ~t[16 + i];
322817466cbSJens Wiklander         }
32332b31808SJens Wiklander     }
324817466cbSJens Wiklander 
325817466cbSJens Wiklander     /*
326817466cbSJens Wiklander      * Prepare SIGMA values
327817466cbSJens Wiklander      */
328817466cbSJens Wiklander     for (i = 0; i < 6; i++) {
329039e02dfSJerome Forissier         SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
330039e02dfSJerome Forissier         SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
331817466cbSJens Wiklander     }
332817466cbSJens Wiklander 
333817466cbSJens Wiklander     /*
334817466cbSJens Wiklander      * Key storage in KC
335817466cbSJens Wiklander      * Order: KL, KR, KA, KB
336817466cbSJens Wiklander      */
337817466cbSJens Wiklander     memset(KC, 0, sizeof(KC));
338817466cbSJens Wiklander 
339817466cbSJens Wiklander     /* Store KL, KR */
34032b31808SJens Wiklander     for (i = 0; i < 8; i++) {
341039e02dfSJerome Forissier         KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
34232b31808SJens Wiklander     }
343817466cbSJens Wiklander 
344817466cbSJens Wiklander     /* Generate KA */
34532b31808SJens Wiklander     for (i = 0; i < 4; ++i) {
346817466cbSJens Wiklander         KC[8 + i] = KC[i] ^ KC[4 + i];
34732b31808SJens Wiklander     }
348817466cbSJens Wiklander 
349817466cbSJens Wiklander     camellia_feistel(KC + 8, SIGMA[0], KC + 10);
350817466cbSJens Wiklander     camellia_feistel(KC + 10, SIGMA[1], KC + 8);
351817466cbSJens Wiklander 
35232b31808SJens Wiklander     for (i = 0; i < 4; ++i) {
353817466cbSJens Wiklander         KC[8 + i] ^= KC[i];
35432b31808SJens Wiklander     }
355817466cbSJens Wiklander 
356817466cbSJens Wiklander     camellia_feistel(KC + 8, SIGMA[2], KC + 10);
357817466cbSJens Wiklander     camellia_feistel(KC + 10, SIGMA[3], KC + 8);
358817466cbSJens Wiklander 
359817466cbSJens Wiklander     if (keybits > 128) {
360817466cbSJens Wiklander         /* Generate KB */
36132b31808SJens Wiklander         for (i = 0; i < 4; ++i) {
362817466cbSJens Wiklander             KC[12 + i] = KC[4 + i] ^ KC[8 + i];
36332b31808SJens Wiklander         }
364817466cbSJens Wiklander 
365817466cbSJens Wiklander         camellia_feistel(KC + 12, SIGMA[4], KC + 14);
366817466cbSJens Wiklander         camellia_feistel(KC + 14, SIGMA[5], KC + 12);
367817466cbSJens Wiklander     }
368817466cbSJens Wiklander 
369817466cbSJens Wiklander     /*
370817466cbSJens Wiklander      * Generating subkeys
371817466cbSJens Wiklander      */
372817466cbSJens Wiklander 
373817466cbSJens Wiklander     /* Manipulating KL */
374817466cbSJens Wiklander     SHIFT_AND_PLACE(idx, 0);
375817466cbSJens Wiklander 
376817466cbSJens Wiklander     /* Manipulating KR */
377817466cbSJens Wiklander     if (keybits > 128) {
378817466cbSJens Wiklander         SHIFT_AND_PLACE(idx, 1);
379817466cbSJens Wiklander     }
380817466cbSJens Wiklander 
381817466cbSJens Wiklander     /* Manipulating KA */
382817466cbSJens Wiklander     SHIFT_AND_PLACE(idx, 2);
383817466cbSJens Wiklander 
384817466cbSJens Wiklander     /* Manipulating KB */
385817466cbSJens Wiklander     if (keybits > 128) {
386817466cbSJens Wiklander         SHIFT_AND_PLACE(idx, 3);
387817466cbSJens Wiklander     }
388817466cbSJens Wiklander 
389817466cbSJens Wiklander     /* Do transpositions */
390817466cbSJens Wiklander     for (i = 0; i < 20; i++) {
391817466cbSJens Wiklander         if (transposes[idx][i] != -1) {
392817466cbSJens Wiklander             RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
393817466cbSJens Wiklander         }
394817466cbSJens Wiklander     }
395817466cbSJens Wiklander 
39632b31808SJens Wiklander     return 0;
397817466cbSJens Wiklander }
398817466cbSJens Wiklander 
399817466cbSJens Wiklander /*
400817466cbSJens Wiklander  * Camellia key schedule (decryption)
401817466cbSJens Wiklander  */
402*b0563631STom Van Eyck #if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
mbedtls_camellia_setkey_dec(mbedtls_camellia_context * ctx,const unsigned char * key,unsigned int keybits)4033d3b0591SJens Wiklander int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
4043d3b0591SJens Wiklander                                 const unsigned char *key,
405817466cbSJens Wiklander                                 unsigned int keybits)
406817466cbSJens Wiklander {
407817466cbSJens Wiklander     int idx, ret;
408817466cbSJens Wiklander     size_t i;
409817466cbSJens Wiklander     mbedtls_camellia_context cty;
410817466cbSJens Wiklander     uint32_t *RK;
411817466cbSJens Wiklander     uint32_t *SK;
412817466cbSJens Wiklander 
413817466cbSJens Wiklander     mbedtls_camellia_init(&cty);
414817466cbSJens Wiklander 
415817466cbSJens Wiklander     /* Also checks keybits */
41632b31808SJens Wiklander     if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
417817466cbSJens Wiklander         goto exit;
41832b31808SJens Wiklander     }
419817466cbSJens Wiklander 
420817466cbSJens Wiklander     ctx->nr = cty.nr;
421817466cbSJens Wiklander     idx = (ctx->nr == 4);
422817466cbSJens Wiklander 
423817466cbSJens Wiklander     RK = ctx->rk;
424817466cbSJens Wiklander     SK = cty.rk + 24 * 2 + 8 * idx * 2;
425817466cbSJens Wiklander 
426817466cbSJens Wiklander     *RK++ = *SK++;
427817466cbSJens Wiklander     *RK++ = *SK++;
428817466cbSJens Wiklander     *RK++ = *SK++;
429817466cbSJens Wiklander     *RK++ = *SK++;
430817466cbSJens Wiklander 
43132b31808SJens Wiklander     for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
432817466cbSJens Wiklander         *RK++ = *SK++;
433817466cbSJens Wiklander         *RK++ = *SK++;
434817466cbSJens Wiklander     }
435817466cbSJens Wiklander 
436817466cbSJens Wiklander     SK -= 2;
437817466cbSJens Wiklander 
438817466cbSJens Wiklander     *RK++ = *SK++;
439817466cbSJens Wiklander     *RK++ = *SK++;
440817466cbSJens Wiklander     *RK++ = *SK++;
441817466cbSJens Wiklander     *RK++ = *SK++;
442817466cbSJens Wiklander 
443817466cbSJens Wiklander exit:
444817466cbSJens Wiklander     mbedtls_camellia_free(&cty);
445817466cbSJens Wiklander 
44632b31808SJens Wiklander     return ret;
447817466cbSJens Wiklander }
448*b0563631STom Van Eyck #endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
449817466cbSJens Wiklander 
450817466cbSJens Wiklander /*
451817466cbSJens Wiklander  * Camellia-ECB block encryption/decryption
452817466cbSJens Wiklander  */
mbedtls_camellia_crypt_ecb(mbedtls_camellia_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])453817466cbSJens Wiklander int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
454817466cbSJens Wiklander                                int mode,
455817466cbSJens Wiklander                                const unsigned char input[16],
456817466cbSJens Wiklander                                unsigned char output[16])
457817466cbSJens Wiklander {
458817466cbSJens Wiklander     int NR;
459817466cbSJens Wiklander     uint32_t *RK, X[4];
46032b31808SJens Wiklander     if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
46132b31808SJens Wiklander         return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
46232b31808SJens Wiklander     }
463817466cbSJens Wiklander 
464817466cbSJens Wiklander     ((void) mode);
465817466cbSJens Wiklander 
466817466cbSJens Wiklander     NR = ctx->nr;
467817466cbSJens Wiklander     RK = ctx->rk;
468817466cbSJens Wiklander 
469039e02dfSJerome Forissier     X[0] = MBEDTLS_GET_UINT32_BE(input,  0);
470039e02dfSJerome Forissier     X[1] = MBEDTLS_GET_UINT32_BE(input,  4);
471039e02dfSJerome Forissier     X[2] = MBEDTLS_GET_UINT32_BE(input,  8);
472039e02dfSJerome Forissier     X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
473817466cbSJens Wiklander 
474817466cbSJens Wiklander     X[0] ^= *RK++;
475817466cbSJens Wiklander     X[1] ^= *RK++;
476817466cbSJens Wiklander     X[2] ^= *RK++;
477817466cbSJens Wiklander     X[3] ^= *RK++;
478817466cbSJens Wiklander 
479817466cbSJens Wiklander     while (NR) {
480817466cbSJens Wiklander         --NR;
481817466cbSJens Wiklander         camellia_feistel(X, RK, X + 2);
482817466cbSJens Wiklander         RK += 2;
483817466cbSJens Wiklander         camellia_feistel(X + 2, RK, X);
484817466cbSJens Wiklander         RK += 2;
485817466cbSJens Wiklander         camellia_feistel(X, RK, X + 2);
486817466cbSJens Wiklander         RK += 2;
487817466cbSJens Wiklander         camellia_feistel(X + 2, RK, X);
488817466cbSJens Wiklander         RK += 2;
489817466cbSJens Wiklander         camellia_feistel(X, RK, X + 2);
490817466cbSJens Wiklander         RK += 2;
491817466cbSJens Wiklander         camellia_feistel(X + 2, RK, X);
492817466cbSJens Wiklander         RK += 2;
493817466cbSJens Wiklander 
494817466cbSJens Wiklander         if (NR) {
495817466cbSJens Wiklander             FL(X[0], X[1], RK[0], RK[1]);
496817466cbSJens Wiklander             RK += 2;
497817466cbSJens Wiklander             FLInv(X[2], X[3], RK[0], RK[1]);
498817466cbSJens Wiklander             RK += 2;
499817466cbSJens Wiklander         }
500817466cbSJens Wiklander     }
501817466cbSJens Wiklander 
502817466cbSJens Wiklander     X[2] ^= *RK++;
503817466cbSJens Wiklander     X[3] ^= *RK++;
504817466cbSJens Wiklander     X[0] ^= *RK++;
505817466cbSJens Wiklander     X[1] ^= *RK++;
506817466cbSJens Wiklander 
507039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_BE(X[2], output,  0);
508039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_BE(X[3], output,  4);
509039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_BE(X[0], output,  8);
510039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
511817466cbSJens Wiklander 
51232b31808SJens Wiklander     return 0;
513817466cbSJens Wiklander }
514817466cbSJens Wiklander 
515817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
516817466cbSJens Wiklander /*
517817466cbSJens Wiklander  * Camellia-CBC buffer encryption/decryption
518817466cbSJens Wiklander  */
mbedtls_camellia_crypt_cbc(mbedtls_camellia_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)519817466cbSJens Wiklander int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
520817466cbSJens Wiklander                                int mode,
521817466cbSJens Wiklander                                size_t length,
522817466cbSJens Wiklander                                unsigned char iv[16],
523817466cbSJens Wiklander                                const unsigned char *input,
524817466cbSJens Wiklander                                unsigned char *output)
525817466cbSJens Wiklander {
526817466cbSJens Wiklander     unsigned char temp[16];
52732b31808SJens Wiklander     if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
52832b31808SJens Wiklander         return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
52932b31808SJens Wiklander     }
530817466cbSJens Wiklander 
53132b31808SJens Wiklander     if (length % 16) {
53232b31808SJens Wiklander         return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
53332b31808SJens Wiklander     }
534817466cbSJens Wiklander 
53532b31808SJens Wiklander     if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
53632b31808SJens Wiklander         while (length > 0) {
537817466cbSJens Wiklander             memcpy(temp, input, 16);
538817466cbSJens Wiklander             mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
539817466cbSJens Wiklander 
54032b31808SJens Wiklander             mbedtls_xor(output, output, iv, 16);
541817466cbSJens Wiklander 
542817466cbSJens Wiklander             memcpy(iv, temp, 16);
543817466cbSJens Wiklander 
544817466cbSJens Wiklander             input  += 16;
545817466cbSJens Wiklander             output += 16;
546817466cbSJens Wiklander             length -= 16;
547817466cbSJens Wiklander         }
54832b31808SJens Wiklander     } else {
54932b31808SJens Wiklander         while (length > 0) {
55032b31808SJens Wiklander             mbedtls_xor(output, input, iv, 16);
551817466cbSJens Wiklander 
552817466cbSJens Wiklander             mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
553817466cbSJens Wiklander             memcpy(iv, output, 16);
554817466cbSJens Wiklander 
555817466cbSJens Wiklander             input  += 16;
556817466cbSJens Wiklander             output += 16;
557817466cbSJens Wiklander             length -= 16;
558817466cbSJens Wiklander         }
559817466cbSJens Wiklander     }
560817466cbSJens Wiklander 
56132b31808SJens Wiklander     return 0;
562817466cbSJens Wiklander }
563817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
564817466cbSJens Wiklander 
565817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
566817466cbSJens Wiklander /*
567817466cbSJens Wiklander  * Camellia-CFB128 buffer encryption/decryption
568817466cbSJens Wiklander  */
mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context * ctx,int mode,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)569817466cbSJens Wiklander int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
570817466cbSJens Wiklander                                   int mode,
571817466cbSJens Wiklander                                   size_t length,
572817466cbSJens Wiklander                                   size_t *iv_off,
573817466cbSJens Wiklander                                   unsigned char iv[16],
574817466cbSJens Wiklander                                   const unsigned char *input,
575817466cbSJens Wiklander                                   unsigned char *output)
576817466cbSJens Wiklander {
577817466cbSJens Wiklander     int c;
5783d3b0591SJens Wiklander     size_t n;
57932b31808SJens Wiklander     if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
58032b31808SJens Wiklander         return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
58132b31808SJens Wiklander     }
5823d3b0591SJens Wiklander 
5833d3b0591SJens Wiklander     n = *iv_off;
58432b31808SJens Wiklander     if (n >= 16) {
58532b31808SJens Wiklander         return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
58632b31808SJens Wiklander     }
587817466cbSJens Wiklander 
58832b31808SJens Wiklander     if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
58932b31808SJens Wiklander         while (length--) {
59032b31808SJens Wiklander             if (n == 0) {
591817466cbSJens Wiklander                 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
59232b31808SJens Wiklander             }
593817466cbSJens Wiklander 
594817466cbSJens Wiklander             c = *input++;
595817466cbSJens Wiklander             *output++ = (unsigned char) (c ^ iv[n]);
596817466cbSJens Wiklander             iv[n] = (unsigned char) c;
597817466cbSJens Wiklander 
598817466cbSJens Wiklander             n = (n + 1) & 0x0F;
599817466cbSJens Wiklander         }
60032b31808SJens Wiklander     } else {
60132b31808SJens Wiklander         while (length--) {
60232b31808SJens Wiklander             if (n == 0) {
603817466cbSJens Wiklander                 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
60432b31808SJens Wiklander             }
605817466cbSJens Wiklander 
606817466cbSJens Wiklander             iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
607817466cbSJens Wiklander 
608817466cbSJens Wiklander             n = (n + 1) & 0x0F;
609817466cbSJens Wiklander         }
610817466cbSJens Wiklander     }
611817466cbSJens Wiklander 
612817466cbSJens Wiklander     *iv_off = n;
613817466cbSJens Wiklander 
61432b31808SJens Wiklander     return 0;
615817466cbSJens Wiklander }
616817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
617817466cbSJens Wiklander 
618817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
619817466cbSJens Wiklander /*
620817466cbSJens Wiklander  * Camellia-CTR buffer encryption/decryption
621817466cbSJens Wiklander  */
mbedtls_camellia_crypt_ctr(mbedtls_camellia_context * ctx,size_t length,size_t * nc_off,unsigned char nonce_counter[16],unsigned char stream_block[16],const unsigned char * input,unsigned char * output)622817466cbSJens Wiklander int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
623817466cbSJens Wiklander                                size_t length,
624817466cbSJens Wiklander                                size_t *nc_off,
625817466cbSJens Wiklander                                unsigned char nonce_counter[16],
626817466cbSJens Wiklander                                unsigned char stream_block[16],
627817466cbSJens Wiklander                                const unsigned char *input,
628817466cbSJens Wiklander                                unsigned char *output)
629817466cbSJens Wiklander {
630817466cbSJens Wiklander     int c, i;
6313d3b0591SJens Wiklander     size_t n;
6323d3b0591SJens Wiklander 
6333d3b0591SJens Wiklander     n = *nc_off;
63432b31808SJens Wiklander     if (n >= 16) {
63532b31808SJens Wiklander         return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
63632b31808SJens Wiklander     }
637817466cbSJens Wiklander 
63832b31808SJens Wiklander     while (length--) {
639817466cbSJens Wiklander         if (n == 0) {
640817466cbSJens Wiklander             mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
641817466cbSJens Wiklander                                        stream_block);
642817466cbSJens Wiklander 
64332b31808SJens Wiklander             for (i = 16; i > 0; i--) {
64432b31808SJens Wiklander                 if (++nonce_counter[i - 1] != 0) {
645817466cbSJens Wiklander                     break;
646817466cbSJens Wiklander                 }
64732b31808SJens Wiklander             }
64832b31808SJens Wiklander         }
649817466cbSJens Wiklander         c = *input++;
650817466cbSJens Wiklander         *output++ = (unsigned char) (c ^ stream_block[n]);
651817466cbSJens Wiklander 
652817466cbSJens Wiklander         n = (n + 1) & 0x0F;
653817466cbSJens Wiklander     }
654817466cbSJens Wiklander 
655817466cbSJens Wiklander     *nc_off = n;
656817466cbSJens Wiklander 
65732b31808SJens Wiklander     return 0;
658817466cbSJens Wiklander }
659817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
660817466cbSJens Wiklander #endif /* !MBEDTLS_CAMELLIA_ALT */
661817466cbSJens Wiklander 
662817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
663817466cbSJens Wiklander 
664817466cbSJens Wiklander /*
665817466cbSJens Wiklander  * Camellia test vectors from:
666817466cbSJens Wiklander  *
667817466cbSJens Wiklander  * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
668817466cbSJens Wiklander  *   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
669817466cbSJens Wiklander  *   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
670817466cbSJens Wiklander  *                      (For each bitlength: Key 0, Nr 39)
671817466cbSJens Wiklander  */
672817466cbSJens Wiklander #define CAMELLIA_TESTS_ECB  2
673817466cbSJens Wiklander 
674817466cbSJens Wiklander static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
675817466cbSJens Wiklander {
676817466cbSJens Wiklander     {
677817466cbSJens Wiklander         { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
678817466cbSJens Wiklander           0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
679817466cbSJens Wiklander         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680817466cbSJens Wiklander           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
681817466cbSJens Wiklander     },
682817466cbSJens Wiklander     {
683817466cbSJens Wiklander         { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
684817466cbSJens Wiklander           0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
685817466cbSJens Wiklander           0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
686817466cbSJens Wiklander         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687817466cbSJens Wiklander           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688817466cbSJens Wiklander           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
689817466cbSJens Wiklander     },
690817466cbSJens Wiklander     {
691817466cbSJens Wiklander         { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
692817466cbSJens Wiklander           0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
693817466cbSJens Wiklander           0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
694817466cbSJens Wiklander           0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
695817466cbSJens Wiklander         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696817466cbSJens Wiklander           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697817466cbSJens Wiklander           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698817466cbSJens Wiklander           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
699817466cbSJens Wiklander     },
700817466cbSJens Wiklander };
701817466cbSJens Wiklander 
702817466cbSJens Wiklander static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
703817466cbSJens Wiklander {
704817466cbSJens Wiklander     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
705817466cbSJens Wiklander       0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
706817466cbSJens Wiklander     { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
707817466cbSJens Wiklander       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
708817466cbSJens Wiklander };
709817466cbSJens Wiklander 
710817466cbSJens Wiklander static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
711817466cbSJens Wiklander {
712817466cbSJens Wiklander     {
713817466cbSJens Wiklander         { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
714817466cbSJens Wiklander           0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
715817466cbSJens Wiklander         { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
716817466cbSJens Wiklander           0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
717817466cbSJens Wiklander     },
718817466cbSJens Wiklander     {
719817466cbSJens Wiklander         { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
720817466cbSJens Wiklander           0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
721817466cbSJens Wiklander         { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
722817466cbSJens Wiklander           0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
723817466cbSJens Wiklander     },
724817466cbSJens Wiklander     {
725817466cbSJens Wiklander         { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
726817466cbSJens Wiklander           0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
727817466cbSJens Wiklander         { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
728817466cbSJens Wiklander           0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
729817466cbSJens Wiklander     }
730817466cbSJens Wiklander };
731817466cbSJens Wiklander 
732817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
733817466cbSJens Wiklander #define CAMELLIA_TESTS_CBC  3
734817466cbSJens Wiklander 
735817466cbSJens Wiklander static const unsigned char camellia_test_cbc_key[3][32] =
736817466cbSJens Wiklander {
737817466cbSJens Wiklander     { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
738817466cbSJens Wiklander       0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
739817466cbSJens Wiklander     ,
740817466cbSJens Wiklander     { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
741817466cbSJens Wiklander       0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
742817466cbSJens Wiklander       0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
743817466cbSJens Wiklander     ,
744817466cbSJens Wiklander     { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
745817466cbSJens Wiklander       0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
746817466cbSJens Wiklander       0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
747817466cbSJens Wiklander       0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
748817466cbSJens Wiklander };
749817466cbSJens Wiklander 
750817466cbSJens Wiklander static const unsigned char camellia_test_cbc_iv[16] =
751817466cbSJens Wiklander 
752817466cbSJens Wiklander { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
753817466cbSJens Wiklander   0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
754817466cbSJens Wiklander ;
755817466cbSJens Wiklander 
756817466cbSJens Wiklander static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
757817466cbSJens Wiklander {
758817466cbSJens Wiklander     { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
759817466cbSJens Wiklander       0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
760817466cbSJens Wiklander     { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
761817466cbSJens Wiklander       0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
762817466cbSJens Wiklander     { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
763817466cbSJens Wiklander       0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
764817466cbSJens Wiklander 
765817466cbSJens Wiklander };
766817466cbSJens Wiklander 
767817466cbSJens Wiklander static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
768817466cbSJens Wiklander {
769817466cbSJens Wiklander     {
770817466cbSJens Wiklander         { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
771817466cbSJens Wiklander           0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
772817466cbSJens Wiklander         { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
773817466cbSJens Wiklander           0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
774817466cbSJens Wiklander         { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
775817466cbSJens Wiklander           0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
776817466cbSJens Wiklander     },
777817466cbSJens Wiklander     {
778817466cbSJens Wiklander         { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
779817466cbSJens Wiklander           0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
780817466cbSJens Wiklander         { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
781817466cbSJens Wiklander           0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
782817466cbSJens Wiklander         { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
783817466cbSJens Wiklander           0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
784817466cbSJens Wiklander     },
785817466cbSJens Wiklander     {
786817466cbSJens Wiklander         { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
787817466cbSJens Wiklander           0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
788817466cbSJens Wiklander         { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
789817466cbSJens Wiklander           0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
790817466cbSJens Wiklander         { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
791817466cbSJens Wiklander           0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
792817466cbSJens Wiklander     }
793817466cbSJens Wiklander };
794817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
795817466cbSJens Wiklander 
796817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
797817466cbSJens Wiklander /*
798817466cbSJens Wiklander  * Camellia-CTR test vectors from:
799817466cbSJens Wiklander  *
800817466cbSJens Wiklander  * http://www.faqs.org/rfcs/rfc5528.html
801817466cbSJens Wiklander  */
802817466cbSJens Wiklander 
803817466cbSJens Wiklander static const unsigned char camellia_test_ctr_key[3][16] =
804817466cbSJens Wiklander {
805817466cbSJens Wiklander     { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
806817466cbSJens Wiklander       0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
807817466cbSJens Wiklander     { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
808817466cbSJens Wiklander       0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
809817466cbSJens Wiklander     { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
810817466cbSJens Wiklander       0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
811817466cbSJens Wiklander };
812817466cbSJens Wiklander 
813817466cbSJens Wiklander static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
814817466cbSJens Wiklander {
815817466cbSJens Wiklander     { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
816817466cbSJens Wiklander       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
817817466cbSJens Wiklander     { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
818817466cbSJens Wiklander       0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
819817466cbSJens Wiklander     { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
820817466cbSJens Wiklander       0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
821817466cbSJens Wiklander };
822817466cbSJens Wiklander 
823817466cbSJens Wiklander static const unsigned char camellia_test_ctr_pt[3][48] =
824817466cbSJens Wiklander {
825817466cbSJens Wiklander     { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
826817466cbSJens Wiklander       0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
827817466cbSJens Wiklander 
828817466cbSJens Wiklander     { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
829817466cbSJens Wiklander       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
830817466cbSJens Wiklander       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
831817466cbSJens Wiklander       0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
832817466cbSJens Wiklander 
833817466cbSJens Wiklander     { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
834817466cbSJens Wiklander       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
835817466cbSJens Wiklander       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
836817466cbSJens Wiklander       0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
837817466cbSJens Wiklander       0x20, 0x21, 0x22, 0x23 }
838817466cbSJens Wiklander };
839817466cbSJens Wiklander 
840817466cbSJens Wiklander static const unsigned char camellia_test_ctr_ct[3][48] =
841817466cbSJens Wiklander {
842817466cbSJens Wiklander     { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
843817466cbSJens Wiklander       0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
844817466cbSJens Wiklander     { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
845817466cbSJens Wiklander       0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
846817466cbSJens Wiklander       0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
847817466cbSJens Wiklander       0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
848817466cbSJens Wiklander     { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
849817466cbSJens Wiklander       0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
850817466cbSJens Wiklander       0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
851817466cbSJens Wiklander       0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
852817466cbSJens Wiklander       0xDF, 0x50, 0x86, 0x96 }
853817466cbSJens Wiklander };
854817466cbSJens Wiklander 
855817466cbSJens Wiklander static const int camellia_test_ctr_len[3] =
856817466cbSJens Wiklander { 16, 32, 36 };
857817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
858817466cbSJens Wiklander 
859817466cbSJens Wiklander /*
860817466cbSJens Wiklander  * Checkup routine
861817466cbSJens Wiklander  */
mbedtls_camellia_self_test(int verbose)862817466cbSJens Wiklander int mbedtls_camellia_self_test(int verbose)
863817466cbSJens Wiklander {
864817466cbSJens Wiklander     int i, j, u, v;
865817466cbSJens Wiklander     unsigned char key[32];
866817466cbSJens Wiklander     unsigned char buf[64];
867817466cbSJens Wiklander     unsigned char src[16];
868817466cbSJens Wiklander     unsigned char dst[16];
869817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
870817466cbSJens Wiklander     unsigned char iv[16];
871817466cbSJens Wiklander #endif
872817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
873817466cbSJens Wiklander     size_t offset, len;
874817466cbSJens Wiklander     unsigned char nonce_counter[16];
875817466cbSJens Wiklander     unsigned char stream_block[16];
876817466cbSJens Wiklander #endif
8777901324dSJerome Forissier     int ret = 1;
878817466cbSJens Wiklander 
879817466cbSJens Wiklander     mbedtls_camellia_context ctx;
880817466cbSJens Wiklander 
8817901324dSJerome Forissier     mbedtls_camellia_init(&ctx);
882817466cbSJens Wiklander     memset(key, 0, 32);
883817466cbSJens Wiklander 
884817466cbSJens Wiklander     for (j = 0; j < 6; j++) {
885817466cbSJens Wiklander         u = j >> 1;
886817466cbSJens Wiklander         v = j & 1;
887817466cbSJens Wiklander 
88832b31808SJens Wiklander         if (verbose != 0) {
889817466cbSJens Wiklander             mbedtls_printf("  CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
890817466cbSJens Wiklander                            (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
89132b31808SJens Wiklander         }
892817466cbSJens Wiklander 
893*b0563631STom Van Eyck #if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
894*b0563631STom Van Eyck         if (v == MBEDTLS_CAMELLIA_DECRYPT) {
895*b0563631STom Van Eyck             if (verbose != 0) {
896*b0563631STom Van Eyck                 mbedtls_printf("skipped\n");
897*b0563631STom Van Eyck             }
898*b0563631STom Van Eyck             continue;
899*b0563631STom Van Eyck         }
900*b0563631STom Van Eyck #endif
901*b0563631STom Van Eyck 
902817466cbSJens Wiklander         for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
903817466cbSJens Wiklander             memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
904817466cbSJens Wiklander 
905*b0563631STom Van Eyck #if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
906817466cbSJens Wiklander             if (v == MBEDTLS_CAMELLIA_DECRYPT) {
907817466cbSJens Wiklander                 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
908817466cbSJens Wiklander                 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
909817466cbSJens Wiklander                 memcpy(dst, camellia_test_ecb_plain[i], 16);
910*b0563631STom Van Eyck             } else
911*b0563631STom Van Eyck #endif
912*b0563631STom Van Eyck             { /* MBEDTLS_CAMELLIA_ENCRYPT */
913817466cbSJens Wiklander                 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
914817466cbSJens Wiklander                 memcpy(src, camellia_test_ecb_plain[i], 16);
915817466cbSJens Wiklander                 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
916817466cbSJens Wiklander             }
917817466cbSJens Wiklander 
918817466cbSJens Wiklander             mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
919817466cbSJens Wiklander 
92032b31808SJens Wiklander             if (memcmp(buf, dst, 16) != 0) {
92132b31808SJens Wiklander                 if (verbose != 0) {
922817466cbSJens Wiklander                     mbedtls_printf("failed\n");
92332b31808SJens Wiklander                 }
9247901324dSJerome Forissier                 goto exit;
925817466cbSJens Wiklander             }
926817466cbSJens Wiklander         }
927817466cbSJens Wiklander 
92832b31808SJens Wiklander         if (verbose != 0) {
929817466cbSJens Wiklander             mbedtls_printf("passed\n");
930817466cbSJens Wiklander         }
93132b31808SJens Wiklander     }
932817466cbSJens Wiklander 
93332b31808SJens Wiklander     if (verbose != 0) {
934817466cbSJens Wiklander         mbedtls_printf("\n");
93532b31808SJens Wiklander     }
936817466cbSJens Wiklander 
937817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
938817466cbSJens Wiklander     /*
939817466cbSJens Wiklander      * CBC mode
940817466cbSJens Wiklander      */
94132b31808SJens Wiklander     for (j = 0; j < 6; j++) {
942817466cbSJens Wiklander         u = j >> 1;
943817466cbSJens Wiklander         v = j  & 1;
944817466cbSJens Wiklander 
94532b31808SJens Wiklander         if (verbose != 0) {
946817466cbSJens Wiklander             mbedtls_printf("  CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
947817466cbSJens Wiklander                            (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
94832b31808SJens Wiklander         }
949817466cbSJens Wiklander 
950817466cbSJens Wiklander         memcpy(src, camellia_test_cbc_iv, 16);
951817466cbSJens Wiklander         memcpy(dst, camellia_test_cbc_iv, 16);
952817466cbSJens Wiklander         memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
953817466cbSJens Wiklander 
954817466cbSJens Wiklander         if (v == MBEDTLS_CAMELLIA_DECRYPT) {
955817466cbSJens Wiklander             mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
956817466cbSJens Wiklander         } else {
957817466cbSJens Wiklander             mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
958817466cbSJens Wiklander         }
959817466cbSJens Wiklander 
960817466cbSJens Wiklander         for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
961817466cbSJens Wiklander 
962817466cbSJens Wiklander             if (v == MBEDTLS_CAMELLIA_DECRYPT) {
963817466cbSJens Wiklander                 memcpy(iv, src, 16);
964817466cbSJens Wiklander                 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
965817466cbSJens Wiklander                 memcpy(dst, camellia_test_cbc_plain[i], 16);
966817466cbSJens Wiklander             } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
967817466cbSJens Wiklander                 memcpy(iv, dst, 16);
968817466cbSJens Wiklander                 memcpy(src, camellia_test_cbc_plain[i], 16);
969817466cbSJens Wiklander                 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
970817466cbSJens Wiklander             }
971817466cbSJens Wiklander 
972817466cbSJens Wiklander             mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
973817466cbSJens Wiklander 
97432b31808SJens Wiklander             if (memcmp(buf, dst, 16) != 0) {
97532b31808SJens Wiklander                 if (verbose != 0) {
976817466cbSJens Wiklander                     mbedtls_printf("failed\n");
97732b31808SJens Wiklander                 }
9787901324dSJerome Forissier                 goto exit;
979817466cbSJens Wiklander             }
980817466cbSJens Wiklander         }
981817466cbSJens Wiklander 
98232b31808SJens Wiklander         if (verbose != 0) {
983817466cbSJens Wiklander             mbedtls_printf("passed\n");
984817466cbSJens Wiklander         }
98532b31808SJens Wiklander     }
986817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
987817466cbSJens Wiklander 
98832b31808SJens Wiklander     if (verbose != 0) {
989817466cbSJens Wiklander         mbedtls_printf("\n");
99032b31808SJens Wiklander     }
991817466cbSJens Wiklander 
992817466cbSJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
993817466cbSJens Wiklander     /*
994817466cbSJens Wiklander      * CTR mode
995817466cbSJens Wiklander      */
99632b31808SJens Wiklander     for (i = 0; i < 6; i++) {
997817466cbSJens Wiklander         u = i >> 1;
998817466cbSJens Wiklander         v = i  & 1;
999817466cbSJens Wiklander 
100032b31808SJens Wiklander         if (verbose != 0) {
1001817466cbSJens Wiklander             mbedtls_printf("  CAMELLIA-CTR-128 (%s): ",
1002817466cbSJens Wiklander                            (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
100332b31808SJens Wiklander         }
1004817466cbSJens Wiklander 
1005817466cbSJens Wiklander         memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1006817466cbSJens Wiklander         memcpy(key, camellia_test_ctr_key[u], 16);
1007817466cbSJens Wiklander 
1008817466cbSJens Wiklander         offset = 0;
1009817466cbSJens Wiklander         mbedtls_camellia_setkey_enc(&ctx, key, 128);
1010817466cbSJens Wiklander 
101132b31808SJens Wiklander         if (v == MBEDTLS_CAMELLIA_DECRYPT) {
1012817466cbSJens Wiklander             len = camellia_test_ctr_len[u];
1013817466cbSJens Wiklander             memcpy(buf, camellia_test_ctr_ct[u], len);
1014817466cbSJens Wiklander 
1015817466cbSJens Wiklander             mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1016817466cbSJens Wiklander                                        buf, buf);
1017817466cbSJens Wiklander 
101832b31808SJens Wiklander             if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
101932b31808SJens Wiklander                 if (verbose != 0) {
1020817466cbSJens Wiklander                     mbedtls_printf("failed\n");
102132b31808SJens Wiklander                 }
10227901324dSJerome Forissier                 goto exit;
1023817466cbSJens Wiklander             }
102432b31808SJens Wiklander         } else {
1025817466cbSJens Wiklander             len = camellia_test_ctr_len[u];
1026817466cbSJens Wiklander             memcpy(buf, camellia_test_ctr_pt[u], len);
1027817466cbSJens Wiklander 
1028817466cbSJens Wiklander             mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1029817466cbSJens Wiklander                                        buf, buf);
1030817466cbSJens Wiklander 
103132b31808SJens Wiklander             if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
103232b31808SJens Wiklander                 if (verbose != 0) {
1033817466cbSJens Wiklander                     mbedtls_printf("failed\n");
103432b31808SJens Wiklander                 }
10357901324dSJerome Forissier                 goto exit;
1036817466cbSJens Wiklander             }
1037817466cbSJens Wiklander         }
1038817466cbSJens Wiklander 
103932b31808SJens Wiklander         if (verbose != 0) {
1040817466cbSJens Wiklander             mbedtls_printf("passed\n");
1041817466cbSJens Wiklander         }
104232b31808SJens Wiklander     }
1043817466cbSJens Wiklander 
104432b31808SJens Wiklander     if (verbose != 0) {
1045817466cbSJens Wiklander         mbedtls_printf("\n");
104632b31808SJens Wiklander     }
1047817466cbSJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
1048817466cbSJens Wiklander 
10497901324dSJerome Forissier     ret = 0;
10507901324dSJerome Forissier 
10517901324dSJerome Forissier exit:
10527901324dSJerome Forissier     mbedtls_camellia_free(&ctx);
105332b31808SJens Wiklander     return ret;
1054817466cbSJens Wiklander }
1055817466cbSJens Wiklander 
1056817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
1057817466cbSJens Wiklander 
1058817466cbSJens Wiklander #endif /* MBEDTLS_CAMELLIA_C */
1059