camellia: fix camellia_self_test failure on compilers where char is unsigned by default
[tropicssl.git] / library / xtea.c
blob97d05fbc285e933ca2656a6543de4141e1f055ae
1 /*
2 * An 32-bit implementation of the XTEA algorithm
4 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the names of PolarSSL or XySSL nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "tropicssl/config.h"
36 #if defined(TROPICSSL_XTEA_C)
38 #include "tropicssl/xtea.h"
40 #include <string.h>
43 * 32-bit integer manipulation macros (big endian)
45 #ifndef GET_ULONG_BE
46 #define GET_ULONG_BE(n,b,i) \
47 { \
48 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
49 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
50 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
51 | ( (unsigned long) (b)[(i) + 3] ); \
53 #endif
55 #ifndef PUT_ULONG_BE
56 #define PUT_ULONG_BE(n,b,i) \
57 { \
58 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
59 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
60 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
61 (b)[(i) + 3] = (unsigned char) ( (n) ); \
63 #endif
66 * XTEA key schedule
68 void xtea_setup(xtea_context * ctx, const unsigned char key[16])
70 int i;
72 memset(ctx, 0, sizeof(xtea_context));
74 for (i = 0; i < 4; i++) {
75 GET_ULONG_BE(ctx->k[i], key, i << 2);
80 * XTEA encrypt function
82 void xtea_crypt_ecb(xtea_context * ctx, int mode,
83 const unsigned char input[8],
84 unsigned char output[8])
86 unsigned long *k, v0, v1, i;
88 k = ctx->k;
90 GET_ULONG_BE(v0, input, 0);
91 GET_ULONG_BE(v1, input, 4);
93 if (mode == XTEA_ENCRYPT) {
94 unsigned long sum = 0, delta = 0x9E3779B9;
96 for (i = 0; i < 32; i++) {
97 v0 +=
98 (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
99 sum += delta;
100 v1 +=
101 (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum +
102 k[(sum >> 11) &
103 3]);
105 } else { /* XTEA_DECRYPT */
106 unsigned long delta = 0x9E3779B9, sum = delta * 32;
108 for (i = 0; i < 32; i++) {
109 v1 -=
110 (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum +
111 k[(sum >> 11) &
112 3]);
113 sum -= delta;
114 v0 -=
115 (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
119 PUT_ULONG_BE(v0, output, 0);
120 PUT_ULONG_BE(v1, output, 4);
123 #if defined(TROPICSSL_SELF_TEST)
125 #include <string.h>
126 #include <stdio.h>
129 * XTEA tests vectors (non-official)
132 static const unsigned char xtea_test_key[6][16] = {
133 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
134 0x0c, 0x0d, 0x0e, 0x0f},
135 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
136 0x0c, 0x0d, 0x0e, 0x0f},
137 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
138 0x0c, 0x0d, 0x0e, 0x0f},
139 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00},
141 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00},
143 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00}
147 static const unsigned char xtea_test_pt[6][8] = {
148 {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
149 {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
150 {0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f},
151 {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
152 {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
153 {0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55}
156 static const unsigned char xtea_test_ct[6][8] = {
157 {0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5},
158 {0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8},
159 {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
160 {0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5},
161 {0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d},
162 {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41}
166 * Checkup routine
168 int xtea_self_test(int verbose)
170 int i;
171 unsigned char buf_in[8];
172 unsigned char buf_out[8];
173 xtea_context ctx;
175 for (i = 0; i < 6; i++) {
176 if (verbose != 0)
177 printf(" XTEA test #%d: ", i + 1);
179 memcpy(buf_in, xtea_test_pt[i], 8);
181 xtea_setup(&ctx, xtea_test_key[i]);
182 xtea_crypt_ecb(&ctx, XTEA_ENCRYPT, buf_in, buf_out);
184 if (memcmp(buf_out, xtea_test_ct[i], 8) != 0) {
185 if (verbose != 0)
186 printf("failed\n");
188 return (1);
191 if (verbose != 0)
192 printf("passed\n");
195 if (verbose != 0)
196 printf("\n");
198 return (0);
201 #endif
203 #endif