1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /**
5    @file saferp.c
6    LTC_SAFER+ Implementation by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9 
10 #ifdef LTC_SAFERP
11 
12 #define LTC_SAFER_TAB_C
13 #include "safer_tab.c"
14 
15 const struct ltc_cipher_descriptor saferp_desc =
16 {
17     "safer+",
18     4,
19     16, 32, 16, 8,
20     &saferp_setup,
21     &saferp_ecb_encrypt,
22     &saferp_ecb_decrypt,
23     &saferp_test,
24     &saferp_done,
25     &saferp_keysize,
26     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
27 };
28 
29 /* ROUND(b,i)
30  *
31  * This is one forward key application.  Note the basic form is
32  * key addition, substitution, key addition.  The safer_ebox and safer_lbox
33  * are the exponentiation box and logarithm boxes respectively.
34  * The value of 'i' is the current round number which allows this
35  * function to be unrolled massively.  Most of LTC_SAFER+'s speed
36  * comes from not having to compute indirect accesses into the
37  * array of 16 bytes b[0..15] which is the block of data
38 */
39 
40 #define ROUND(b, i) do {                                                                         \
41     b[0]  = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255;    \
42     b[1]  = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1];            \
43     b[2]  = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2];            \
44     b[3]  = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255;    \
45     b[4]  = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255;    \
46     b[5]  = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5];            \
47     b[6]  = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6];            \
48     b[7]  = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255;    \
49     b[8]  = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255;    \
50     b[9]  = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9];            \
51     b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10];         \
52     b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \
53     b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \
54     b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13];         \
55     b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14];         \
56     b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; \
57 } while (0)
58 
59 /* This is one inverse key application */
60 #define iROUND(b, i) do {                                                                        \
61     b[0]  = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0];            \
62     b[1]  = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255;    \
63     b[2]  = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255;    \
64     b[3]  = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3];            \
65     b[4]  = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4];            \
66     b[5]  = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255;    \
67     b[6]  = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255;    \
68     b[7]  = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7];            \
69     b[8]  = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8];            \
70     b[9]  = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255;    \
71     b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \
72     b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11];         \
73     b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12];         \
74     b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \
75     b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \
76     b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15];         \
77 } while (0)
78 
79 /* This is a forward single layer PHT transform.  */
80 #define PHT(b) do {                                          \
81     b[0]  = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255;     \
82     b[2]  = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255;     \
83     b[4]  = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255;     \
84     b[6]  = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255;     \
85     b[8]  = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255;     \
86     b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \
87     b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \
88     b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; \
89 } while (0)
90 
91 /* This is an inverse single layer PHT transform */
92 #define iPHT(b) do {                                          \
93     b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255;  \
94     b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255;  \
95     b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255;  \
96     b[9]  = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255;      \
97     b[7]  = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255;      \
98     b[5]  = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255;      \
99     b[3]  = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255;      \
100     b[1]  = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255;      \
101  } while (0)
102 
103 /* This is the "Armenian" Shuffle.  It takes the input from b and stores it in b2 */
104 #define SHUF(b, b2) do {                                         \
105     b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15];   \
106     b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5];      \
107     b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \
108     b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3];  \
109 } while (0)
110 
111 /* This is the inverse shuffle.  It takes from b and gives to b2 */
112 #define iSHUF(b, b2) do {                                          \
113     b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15];      \
114     b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13];      \
115     b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1];      \
116     b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3];  \
117 } while (0)
118 
119 /* The complete forward Linear Transform layer.
120  * Note that alternating usage of b and b2.
121  * Each round of LT starts in 'b' and ends in 'b2'.
122  */
123 #define LT(b, b2) do {        \
124     PHT(b);  SHUF(b, b2);     \
125     PHT(b2); SHUF(b2, b);     \
126     PHT(b);  SHUF(b, b2);     \
127     PHT(b2);                  \
128 } while (0)
129 
130 /* This is the inverse linear transform layer.  */
131 #define iLT(b, b2) do {       \
132     iPHT(b);                  \
133     iSHUF(b, b2); iPHT(b2);   \
134     iSHUF(b2, b); iPHT(b);    \
135     iSHUF(b, b2); iPHT(b2);   \
136 } while (0)
137 
138 #ifdef LTC_SMALL_CODE
139 
s_round(unsigned char * b,int i,const symmetric_key * skey)140 static void s_round(unsigned char *b, int i, const symmetric_key *skey)
141 {
142    ROUND(b, i);
143 }
144 
s_iround(unsigned char * b,int i,const symmetric_key * skey)145 static void s_iround(unsigned char *b, int i, const symmetric_key *skey)
146 {
147    iROUND(b, i);
148 }
149 
s_lt(unsigned char * b,unsigned char * b2)150 static void s_lt(unsigned char *b, unsigned char *b2)
151 {
152    LT(b, b2);
153 }
154 
s_ilt(unsigned char * b,unsigned char * b2)155 static void s_ilt(unsigned char *b, unsigned char *b2)
156 {
157    iLT(b, b2);
158 }
159 
160 #undef ROUND
161 #define ROUND(b, i) s_round(b, i, skey)
162 
163 #undef iROUND
164 #define iROUND(b, i) s_iround(b, i, skey)
165 
166 #undef LT
167 #define LT(b, b2) s_lt(b, b2)
168 
169 #undef iLT
170 #define iLT(b, b2) s_ilt(b, b2)
171 
172 #endif
173 
174 /* These are the 33, 128-bit bias words for the key schedule */
175 static const unsigned char safer_bias[33][16] = {
176 {  70, 151, 177, 186, 163, 183,  16,  10, 197,  55, 179, 201,  90,  40, 172, 100},
177 { 236, 171, 170, 198, 103, 149,  88,  13, 248, 154, 246, 110, 102, 220,   5,  61},
178 { 138, 195, 216, 137, 106, 233,  54,  73,  67, 191, 235, 212, 150, 155, 104, 160},
179 {  93,  87, 146,  31, 213, 113,  92, 187,  34, 193, 190, 123, 188, 153,  99, 148},
180 {  42,  97, 184,  52,  50,  25, 253, 251,  23,  64, 230,  81,  29,  65,  68, 143},
181 { 221,   4, 128, 222, 231,  49, 214, 127,   1, 162, 247,  57, 218, 111,  35, 202},
182 {  58, 208,  28, 209,  48,  62,  18, 161, 205,  15, 224, 168, 175, 130,  89,  44},
183 { 125, 173, 178, 239, 194, 135, 206, 117,   6,  19,   2, 144,  79,  46, 114,  51},
184 { 192, 141, 207, 169, 129, 226, 196,  39,  47, 108, 122, 159,  82, 225,  21,  56},
185 { 252,  32,  66, 199,   8, 228,   9,  85,  94, 140,  20, 118,  96, 255, 223, 215},
186 { 250,  11,  33,   0,  26, 249, 166, 185, 232, 158,  98,  76, 217, 145,  80, 210},
187 {  24, 180,   7, 132, 234,  91, 164, 200,  14, 203,  72, 105,  75,  78, 156,  53},
188 {  69,  77,  84, 229,  37,  60,  12,  74, 139,  63, 204, 167, 219, 107, 174, 244},
189 {  45, 243, 124, 109, 157, 181,  38, 116, 242, 147,  83, 176, 240,  17, 237, 131},
190 { 182,   3,  22, 115,  59,  30, 142, 112, 189, 134,  27,  71, 126,  36,  86, 241},
191 { 136,  70, 151, 177, 186, 163, 183,  16,  10, 197,  55, 179, 201,  90,  40, 172},
192 { 220, 134, 119, 215, 166,  17, 251, 244, 186, 146, 145, 100, 131, 241,  51, 239},
193 {  44, 181, 178,  43, 136, 209, 153, 203, 140, 132,  29,  20, 129, 151, 113, 202},
194 { 163, 139,  87,  60, 130, 196,  82,  92,  28, 232, 160,   4, 180, 133,  74, 246},
195 {  84, 182, 223,  12,  26, 142, 222, 224,  57, 252,  32, 155,  36,  78, 169, 152},
196 { 171, 242,  96, 208, 108, 234, 250, 199, 217,   0, 212,  31, 110,  67, 188, 236},
197 { 137, 254, 122,  93,  73, 201,  50, 194, 249, 154, 248, 109,  22, 219,  89, 150},
198 { 233, 205, 230,  70,  66, 143,  10, 193, 204, 185, 101, 176, 210, 198, 172,  30},
199 {  98,  41,  46,  14, 116,  80,   2,  90, 195,  37, 123, 138,  42,  91, 240,   6},
200 {  71, 111, 112, 157, 126,  16, 206,  18,  39, 213,  76,  79, 214, 121,  48, 104},
201 { 117, 125, 228, 237, 128, 106, 144,  55, 162,  94, 118, 170, 197, 127,  61, 175},
202 { 229,  25,  97, 253,  77, 124, 183,  11, 238, 173,  75,  34, 245, 231, 115,  35},
203 { 200,   5, 225, 102, 221, 179,  88, 105,  99,  86,  15, 161,  49, 149,  23,   7},
204 {  40,   1,  45, 226, 147, 190,  69,  21, 174, 120,   3, 135, 164, 184,  56, 207},
205 {   8, 103,   9, 148, 235,  38, 168, 107, 189,  24,  52,  27, 187, 191, 114, 247},
206 {  53,  72, 156,  81,  47,  59,  85, 227, 192, 159, 216, 211, 243, 141, 177, 255},
207 {  62, 220, 134, 119, 215, 166,  17, 251, 244, 186, 146, 145, 100, 131, 241,  51}};
208 
209  /**
210     Initialize the LTC_SAFER+ block cipher
211     @param key The symmetric key you wish to pass
212     @param keylen The key length in bytes
213     @param num_rounds The number of rounds desired (0 for default)
214     @param skey The key in as scheduled by this function.
215     @return CRYPT_OK if successful
216  */
saferp_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)217 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
218 {
219    unsigned x, y, z;
220    unsigned char t[33];
221    static const int rounds[3] = { 8, 12, 16 };
222 
223    LTC_ARGCHK(key  != NULL);
224    LTC_ARGCHK(skey != NULL);
225 
226    /* check arguments */
227    if (keylen != 16 && keylen != 24 && keylen != 32) {
228       return CRYPT_INVALID_KEYSIZE;
229    }
230 
231    /* Is the number of rounds valid?  Either use zero for default or
232     * 8,12,16 rounds for 16,24,32 byte keys
233     */
234    if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) {
235       return CRYPT_INVALID_ROUNDS;
236    }
237 
238    /* 128 bit key version */
239    if (keylen == 16) {
240        /* copy key into t */
241        for (x = y = 0; x < 16; x++) {
242            t[x] = key[x];
243            y ^= key[x];
244        }
245        t[16] = y;
246 
247        /* make round keys */
248        for (x = 0; x < 16; x++) {
249            skey->saferp.K[0][x] = t[x];
250        }
251 
252        /* make the 16 other keys as a transformation of the first key */
253        for (x = 1; x < 17; x++) {
254            /* rotate 3 bits each */
255            for (y = 0; y < 17; y++) {
256                t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
257            }
258 
259            /* select and add */
260            z = x;
261            for (y = 0; y < 16; y++) {
262                skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
263                if (++z == 17) { z = 0; }
264            }
265        }
266        skey->saferp.rounds = 8;
267    } else if (keylen == 24) {
268        /* copy key into t */
269        for (x = y = 0; x < 24; x++) {
270            t[x] = key[x];
271            y ^= key[x];
272        }
273        t[24] = y;
274 
275        /* make round keys */
276        for (x = 0; x < 16; x++) {
277            skey->saferp.K[0][x] = t[x];
278        }
279 
280        for (x = 1; x < 25; x++) {
281            /* rotate 3 bits each */
282            for (y = 0; y < 25; y++) {
283                t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
284            }
285 
286            /* select and add */
287            z = x;
288            for (y = 0; y < 16; y++) {
289                skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
290                if (++z == 25) { z = 0; }
291            }
292        }
293        skey->saferp.rounds = 12;
294    } else {
295        /* copy key into t */
296        for (x = y = 0; x < 32; x++) {
297            t[x] = key[x];
298            y ^= key[x];
299        }
300        t[32] = y;
301 
302        /* make round keys */
303        for (x = 0; x < 16; x++) {
304            skey->saferp.K[0][x] = t[x];
305        }
306 
307        for (x = 1; x < 33; x++) {
308            /* rotate 3 bits each */
309            for (y = 0; y < 33; y++) {
310                t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
311            }
312 
313            /* select and add */
314            z = x;
315            for (y = 0; y < 16; y++) {
316                skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
317                if (++z == 33) { z = 0; }
318            }
319        }
320        skey->saferp.rounds = 16;
321    }
322 #ifdef LTC_CLEAN_STACK
323    zeromem(t, sizeof(t));
324 #endif
325    return CRYPT_OK;
326 }
327 
328 /**
329   Encrypts a block of text with LTC_SAFER+
330   @param pt The input plaintext (16 bytes)
331   @param ct The output ciphertext (16 bytes)
332   @param skey The key as scheduled
333   @return CRYPT_OK if successful
334 */
saferp_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)335 int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
336 {
337    unsigned char b[16];
338    int x;
339 
340    LTC_ARGCHK(pt   != NULL);
341    LTC_ARGCHK(ct   != NULL);
342    LTC_ARGCHK(skey != NULL);
343 
344    if (skey->saferp.rounds < 8 || skey->saferp.rounds > 16) {
345        return CRYPT_INVALID_ROUNDS;
346    }
347 
348    /* do eight rounds */
349    for (x = 0; x < 16; x++) {
350        b[x] = pt[x];
351    }
352    ROUND(b,  0);  LT(b, ct);
353    ROUND(ct, 2);  LT(ct, b);
354    ROUND(b,  4);  LT(b, ct);
355    ROUND(ct, 6);  LT(ct, b);
356    ROUND(b,  8);  LT(b, ct);
357    ROUND(ct, 10); LT(ct, b);
358    ROUND(b,  12); LT(b, ct);
359    ROUND(ct, 14); LT(ct, b);
360    /* 192-bit key? */
361    if (skey->saferp.rounds > 8) {
362       ROUND(b, 16);  LT(b, ct);
363       ROUND(ct, 18); LT(ct, b);
364       ROUND(b, 20);  LT(b, ct);
365       ROUND(ct, 22); LT(ct, b);
366    }
367    /* 256-bit key? */
368    if (skey->saferp.rounds > 12) {
369       ROUND(b, 24);  LT(b, ct);
370       ROUND(ct, 26); LT(ct, b);
371       ROUND(b, 28);  LT(b, ct);
372       ROUND(ct, 30); LT(ct, b);
373    }
374    ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
375    ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
376    ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
377    ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
378    ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
379    ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
380    ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
381    ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
382    ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
383    ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
384    ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
385    ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
386    ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
387    ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
388    ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
389    ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
390 #ifdef LTC_CLEAN_STACK
391    zeromem(b, sizeof(b));
392 #endif
393    return CRYPT_OK;
394 }
395 
396 /**
397   Decrypts a block of text with LTC_SAFER+
398   @param ct The input ciphertext (16 bytes)
399   @param pt The output plaintext (16 bytes)
400   @param skey The key as scheduled
401   @return CRYPT_OK if successful
402 */
saferp_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)403 int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
404 {
405    unsigned char b[16];
406    int x;
407 
408    LTC_ARGCHK(pt   != NULL);
409    LTC_ARGCHK(ct   != NULL);
410    LTC_ARGCHK(skey != NULL);
411 
412    if (skey->saferp.rounds < 8 || skey->saferp.rounds > 16) {
413        return CRYPT_INVALID_ROUNDS;
414    }
415 
416    /* do eight rounds */
417    b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
418    b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
419    b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
420    b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
421    b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
422    b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
423    b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
424    b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
425    b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
426    b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
427    b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
428    b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
429    b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
430    b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
431    b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
432    b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
433    /* 256-bit key? */
434    if (skey->saferp.rounds > 12) {
435       iLT(b, pt); iROUND(pt, 30);
436       iLT(pt, b); iROUND(b, 28);
437       iLT(b, pt); iROUND(pt, 26);
438       iLT(pt, b); iROUND(b, 24);
439    }
440    /* 192-bit key? */
441    if (skey->saferp.rounds > 8) {
442       iLT(b, pt); iROUND(pt, 22);
443       iLT(pt, b); iROUND(b, 20);
444       iLT(b, pt); iROUND(pt, 18);
445       iLT(pt, b); iROUND(b, 16);
446    }
447    iLT(b, pt); iROUND(pt, 14);
448    iLT(pt, b); iROUND(b, 12);
449    iLT(b, pt); iROUND(pt,10);
450    iLT(pt, b); iROUND(b, 8);
451    iLT(b, pt); iROUND(pt,6);
452    iLT(pt, b); iROUND(b, 4);
453    iLT(b, pt); iROUND(pt,2);
454    iLT(pt, b); iROUND(b, 0);
455    for (x = 0; x < 16; x++) {
456        pt[x] = b[x];
457    }
458 #ifdef LTC_CLEAN_STACK
459    zeromem(b, sizeof(b));
460 #endif
461    return CRYPT_OK;
462 }
463 
464 /**
465   Performs a self-test of the LTC_SAFER+ block cipher
466   @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
467 */
saferp_test(void)468 int saferp_test(void)
469 {
470  #ifndef LTC_TEST
471     return CRYPT_NOP;
472  #else
473    static const struct {
474        int keylen;
475        unsigned char key[32], pt[16], ct[16];
476    } tests[] = {
477        {
478            16,
479            { 41, 35, 190, 132, 225, 108, 214, 174,
480              82, 144, 73, 241, 241, 187, 233, 235 },
481            { 179, 166, 219, 60, 135, 12, 62, 153,
482              36, 94, 13, 28, 6, 183, 71, 222 },
483            { 224, 31, 182, 10, 12, 255, 84, 70,
484              127, 13, 89, 249, 9, 57, 165, 220 }
485        }, {
486            24,
487            { 72, 211, 143, 117, 230, 217, 29, 42,
488              229, 192, 247, 43, 120, 129, 135, 68,
489              14, 95, 80, 0, 212, 97, 141, 190 },
490            { 123, 5, 21, 7, 59, 51, 130, 31,
491              24, 112, 146, 218, 100, 84, 206, 177 },
492            { 92, 136, 4, 63, 57, 95, 100, 0,
493              150, 130, 130, 16, 193, 111, 219, 133 }
494        }, {
495            32,
496            { 243, 168, 141, 254, 190, 242, 235, 113,
497              255, 160, 208, 59, 117, 6, 140, 126,
498              135, 120, 115, 77, 208, 190, 130, 190,
499              219, 194, 70, 65, 43, 140, 250, 48 },
500            { 127, 112, 240, 167, 84, 134, 50, 149,
501              170, 91, 104, 19, 11, 230, 252, 245 },
502            { 88, 11, 25, 36, 172, 229, 202, 213,
503              170, 65, 105, 153, 220, 104, 153, 138 }
504        }
505     };
506 
507    unsigned char tmp[2][16];
508    symmetric_key skey;
509    int err, i, y;
510 
511    for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
512       if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK)  {
513          return err;
514       }
515       saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey);
516       saferp_ecb_decrypt(tmp[0], tmp[1], &skey);
517 
518       /* compare */
519       if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "Safer+ Encrypt", i) ||
520             compare_testvector(tmp[1], 16, tests[i].pt, 16, "Safer+ Decrypt", i)) {
521          return CRYPT_FAIL_TESTVECTOR;
522       }
523 
524       /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
525       for (y = 0; y < 16; y++) tmp[0][y] = 0;
526       for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey);
527       for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey);
528       for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
529    }
530 
531    return CRYPT_OK;
532  #endif
533 }
534 
535 /** Terminate the context
536    @param skey    The scheduled key
537 */
saferp_done(symmetric_key * skey)538 void saferp_done(symmetric_key *skey)
539 {
540   LTC_UNUSED_PARAM(skey);
541 }
542 
543 /**
544   Gets suitable key size
545   @param keysize [in/out] The length of the recommended key (in bytes).  This function will store the suitable size back in this variable.
546   @return CRYPT_OK if the input key size is acceptable.
547 */
saferp_keysize(int * keysize)548 int saferp_keysize(int *keysize)
549 {
550    LTC_ARGCHK(keysize != NULL);
551 
552    if (*keysize < 16) {
553       return CRYPT_INVALID_KEYSIZE;
554    }
555    if (*keysize < 24) {
556       *keysize = 16;
557    } else if (*keysize < 32) {
558       *keysize = 24;
559    } else {
560       *keysize = 32;
561    }
562    return CRYPT_OK;
563 }
564 
565 #endif
566 
567 
568