/src/nettle/camellia-absorb.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* camellia-absorb.c |
2 | | |
3 | | Final key setup processing for the camellia block cipher. |
4 | | |
5 | | Copyright (C) 2006,2007 NTT |
6 | | (Nippon Telegraph and Telephone Corporation). |
7 | | |
8 | | Copyright (C) 2010 Niels Möller |
9 | | |
10 | | This file is part of GNU Nettle. |
11 | | |
12 | | GNU Nettle is free software: you can redistribute it and/or |
13 | | modify it under the terms of either: |
14 | | |
15 | | * the GNU Lesser General Public License as published by the Free |
16 | | Software Foundation; either version 3 of the License, or (at your |
17 | | option) any later version. |
18 | | |
19 | | or |
20 | | |
21 | | * the GNU General Public License as published by the Free |
22 | | Software Foundation; either version 2 of the License, or (at your |
23 | | option) any later version. |
24 | | |
25 | | or both in parallel, as here. |
26 | | |
27 | | GNU Nettle is distributed in the hope that it will be useful, |
28 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
30 | | General Public License for more details. |
31 | | |
32 | | You should have received copies of the GNU General Public License and |
33 | | the GNU Lesser General Public License along with this program. If |
34 | | not, see http://www.gnu.org/licenses/. |
35 | | */ |
36 | | |
37 | | /* |
38 | | * Algorithm Specification |
39 | | * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html |
40 | | */ |
41 | | |
42 | | /* Based on camellia.c ver 1.2.0, see |
43 | | http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz. |
44 | | */ |
45 | | |
46 | | #if HAVE_CONFIG_H |
47 | | # include "config.h" |
48 | | #endif |
49 | | |
50 | | /* For CHAR_BIT, needed by HAVE_NATIVE_64_BIT */ |
51 | | #include <limits.h> |
52 | | |
53 | | #include "camellia-internal.h" |
54 | | |
55 | | #include "macros.h" |
56 | | |
57 | | void |
58 | | _nettle_camellia_absorb(unsigned nkeys, uint64_t *dst, uint64_t *subkey) |
59 | 0 | { |
60 | 0 | uint64_t kw2, kw4; |
61 | 0 | uint32_t dw, tl, tr; |
62 | 0 | unsigned i; |
63 | | |
64 | | /* At this point, the subkey array contains the subkeys as described |
65 | | in the spec, 26 for short keys and 34 for large keys. */ |
66 | | |
67 | | /* absorb kw2 to other subkeys */ |
68 | 0 | kw2 = subkey[1]; |
69 | |
|
70 | 0 | subkey[3] ^= kw2; |
71 | 0 | subkey[5] ^= kw2; |
72 | 0 | subkey[7] ^= kw2; |
73 | 0 | for (i = 8; i < nkeys; i += 8) |
74 | 0 | { |
75 | | /* FIXME: gcc for x86_32 is smart enough to fetch the 32 low bits |
76 | | and xor the result into the 32 high bits, but it still generates |
77 | | worse code than for explicit 32-bit operations. */ |
78 | 0 | kw2 ^= (kw2 & ~subkey[i+1]) << 32; |
79 | 0 | dw = (kw2 & subkey[i+1]) >> 32; kw2 ^= ROTL32(1, dw); |
80 | |
|
81 | 0 | subkey[i+3] ^= kw2; |
82 | 0 | subkey[i+5] ^= kw2; |
83 | 0 | subkey[i+7] ^= kw2; |
84 | 0 | } |
85 | 0 | subkey[i] ^= kw2; |
86 | | |
87 | | /* absorb kw4 to other subkeys */ |
88 | 0 | kw4 = subkey[nkeys + 1]; |
89 | |
|
90 | 0 | for (i = nkeys - 8; i > 0; i -= 8) |
91 | 0 | { |
92 | 0 | subkey[i+6] ^= kw4; |
93 | 0 | subkey[i+4] ^= kw4; |
94 | 0 | subkey[i+2] ^= kw4; |
95 | 0 | kw4 ^= (kw4 & ~subkey[i]) << 32; |
96 | 0 | dw = (kw4 & subkey[i]) >> 32; kw4 ^= ROTL32(1, dw); |
97 | 0 | } |
98 | |
|
99 | 0 | subkey[6] ^= kw4; |
100 | 0 | subkey[4] ^= kw4; |
101 | 0 | subkey[2] ^= kw4; |
102 | 0 | subkey[0] ^= kw4; |
103 | | |
104 | | /* key XOR is end of F-function */ |
105 | 0 | dst[0] = subkey[0] ^ subkey[2]; |
106 | 0 | dst[1] = subkey[3]; |
107 | |
|
108 | 0 | dst[2] = subkey[2] ^ subkey[4]; |
109 | 0 | dst[3] = subkey[3] ^ subkey[5]; |
110 | 0 | dst[4] = subkey[4] ^ subkey[6]; |
111 | 0 | dst[5] = subkey[5] ^ subkey[7]; |
112 | |
|
113 | 0 | for (i = 8; i < nkeys; i += 8) |
114 | 0 | { |
115 | 0 | tl = (subkey[i+2] >> 32) ^ (subkey[i+2] & ~subkey[i]); |
116 | 0 | dw = tl & (subkey[i] >> 32); |
117 | 0 | tr = subkey[i+2] ^ ROTL32(1, dw); |
118 | 0 | dst[i-2] = subkey[i-2] ^ ( ((uint64_t) tl << 32) | tr); |
119 | |
|
120 | 0 | dst[i-1] = subkey[i]; |
121 | 0 | dst[i] = subkey[i+1]; |
122 | |
|
123 | 0 | tl = (subkey[i-1] >> 32) ^ (subkey[i-1] & ~subkey[i+1]); |
124 | 0 | dw = tl & (subkey[i+1] >> 32); |
125 | 0 | tr = subkey[i-1] ^ ROTL32(1, dw); |
126 | 0 | dst[i+1] = subkey[i+3] ^ ( ((uint64_t) tl << 32) | tr); |
127 | |
|
128 | 0 | dst[i+2] = subkey[i+2] ^ subkey[i+4]; |
129 | 0 | dst[i+3] = subkey[i+3] ^ subkey[i+5]; |
130 | 0 | dst[i+4] = subkey[i+4] ^ subkey[i+6]; |
131 | 0 | dst[i+5] = subkey[i+5] ^ subkey[i+7]; |
132 | 0 | } |
133 | 0 | dst[i-2] = subkey[i-2]; |
134 | 0 | dst[i-1] = subkey[i] ^ subkey[i-1]; |
135 | |
|
136 | | #if !HAVE_NATIVE_64_BIT |
137 | | for (i = 0; i < nkeys; i += 8) |
138 | | { |
139 | | /* apply the inverse of the last half of F-function */ |
140 | | CAMELLIA_F_HALF_INV(dst[i+1]); |
141 | | CAMELLIA_F_HALF_INV(dst[i+2]); |
142 | | CAMELLIA_F_HALF_INV(dst[i+3]); |
143 | | CAMELLIA_F_HALF_INV(dst[i+4]); |
144 | | CAMELLIA_F_HALF_INV(dst[i+5]); |
145 | | CAMELLIA_F_HALF_INV(dst[i+6]); |
146 | | } |
147 | | #endif |
148 | | |
149 | 0 | } |