diff options
Diffstat (limited to 'src/lib/libcrypto/modes/cfb128.c')
-rw-r--r-- | src/lib/libcrypto/modes/cfb128.c | 268 |
1 files changed, 141 insertions, 127 deletions
diff --git a/src/lib/libcrypto/modes/cfb128.c b/src/lib/libcrypto/modes/cfb128.c index 8555ce0552..f538a2b11c 100644 --- a/src/lib/libcrypto/modes/cfb128.c +++ b/src/lib/libcrypto/modes/cfb128.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cfb128.c,v 1.5 2022/11/26 16:08:53 tb Exp $ */ | 1 | /* $OpenBSD: cfb128.c,v 1.6 2023/07/08 14:55:36 beck Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -7,7 +7,7 @@ | |||
7 | * are met: | 7 | * are met: |
8 | * | 8 | * |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * | 11 | * |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in | 13 | * notice, this list of conditions and the following disclaimer in |
@@ -63,172 +63,186 @@ | |||
63 | * used. The extra state information to record how much of the | 63 | * used. The extra state information to record how much of the |
64 | * 128bit block we have used is contained in *num; | 64 | * 128bit block we have used is contained in *num; |
65 | */ | 65 | */ |
66 | void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, | 66 | void |
67 | size_t len, const void *key, | 67 | CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, |
68 | unsigned char ivec[16], int *num, | 68 | size_t len, const void *key, |
69 | int enc, block128_f block) | 69 | unsigned char ivec[16], int *num, |
70 | int enc, block128_f block) | ||
70 | { | 71 | { |
71 | unsigned int n; | 72 | unsigned int n; |
72 | size_t l = 0; | 73 | size_t l = 0; |
73 | 74 | ||
74 | n = *num; | 75 | n = *num; |
75 | 76 | ||
76 | if (enc) { | 77 | if (enc) { |
77 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | 78 | #if !defined(OPENSSL_SMALL_FOOTPRINT) |
78 | if (16%sizeof(size_t) == 0) do { /* always true actually */ | 79 | if (16 % sizeof(size_t) == 0) |
79 | while (n && len) { | 80 | do { /* always true actually */ |
80 | *(out++) = ivec[n] ^= *(in++); | 81 | while (n && len) { |
81 | --len; | 82 | *(out++) = ivec[n] ^= *(in++); |
82 | n = (n+1) % 16; | 83 | --len; |
83 | } | 84 | n = (n + 1) % 16; |
85 | } | ||
84 | #ifdef __STRICT_ALIGNMENT | 86 | #ifdef __STRICT_ALIGNMENT |
85 | if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) | 87 | if (((size_t)in|(size_t)out|(size_t)ivec) % |
86 | break; | 88 | sizeof(size_t) != 0) |
89 | break; | ||
87 | #endif | 90 | #endif |
88 | while (len>=16) { | 91 | while (len >= 16) { |
89 | (*block)(ivec, ivec, key); | 92 | (*block)(ivec, ivec, key); |
90 | for (; n<16; n+=sizeof(size_t)) { | 93 | for (; n < 16; n += sizeof(size_t)) { |
91 | *(size_t*)(out+n) = | 94 | *(size_t *)(out + n) = |
92 | *(size_t*)(ivec+n) ^= *(size_t*)(in+n); | 95 | *(size_t *)(ivec + n) ^= *(size_t *)(in + |
93 | } | 96 | n); |
94 | len -= 16; | 97 | } |
95 | out += 16; | 98 | len -= 16; |
96 | in += 16; | 99 | out += 16; |
97 | n = 0; | 100 | in += 16; |
98 | } | 101 | n = 0; |
99 | if (len) { | 102 | } |
100 | (*block)(ivec, ivec, key); | 103 | if (len) { |
101 | while (len--) { | 104 | (*block)(ivec, ivec, key); |
102 | out[n] = ivec[n] ^= in[n]; | 105 | while (len--) { |
103 | ++n; | 106 | out[n] = ivec[n] ^= in[n]; |
104 | } | 107 | ++n; |
105 | } | 108 | } |
106 | *num = n; | 109 | } |
107 | return; | 110 | *num = n; |
108 | } while (0); | 111 | return; |
112 | } while (0); | ||
109 | /* the rest would be commonly eliminated by x86* compiler */ | 113 | /* the rest would be commonly eliminated by x86* compiler */ |
110 | #endif | 114 | #endif |
111 | while (l<len) { | 115 | while (l < len) { |
112 | if (n == 0) { | 116 | if (n == 0) { |
113 | (*block)(ivec, ivec, key); | 117 | (*block)(ivec, ivec, key); |
118 | } | ||
119 | out[l] = ivec[n] ^= in[l]; | ||
120 | ++l; | ||
121 | n = (n + 1) % 16; | ||
114 | } | 122 | } |
115 | out[l] = ivec[n] ^= in[l]; | 123 | *num = n; |
116 | ++l; | 124 | } else { |
117 | n = (n+1) % 16; | ||
118 | } | ||
119 | *num = n; | ||
120 | } else { | ||
121 | #if !defined(OPENSSL_SMALL_FOOTPRINT) | 125 | #if !defined(OPENSSL_SMALL_FOOTPRINT) |
122 | if (16%sizeof(size_t) == 0) do { /* always true actually */ | 126 | if (16 % sizeof(size_t) == 0) |
123 | while (n && len) { | 127 | do { /* always true actually */ |
124 | unsigned char c; | 128 | while (n && len) { |
125 | *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c; | 129 | unsigned char c; |
126 | --len; | 130 | *(out++) = ivec[n] ^ (c = *(in++)); |
127 | n = (n+1) % 16; | 131 | ivec[n] = c; |
128 | } | 132 | --len; |
133 | n = (n + 1) % 16; | ||
134 | } | ||
129 | #ifdef __STRICT_ALIGNMENT | 135 | #ifdef __STRICT_ALIGNMENT |
130 | if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) | 136 | if (((size_t)in|(size_t)out|(size_t)ivec) % |
131 | break; | 137 | sizeof(size_t) != 0) |
138 | break; | ||
132 | #endif | 139 | #endif |
133 | while (len>=16) { | 140 | while (len >= 16) { |
134 | (*block)(ivec, ivec, key); | 141 | (*block)(ivec, ivec, key); |
135 | for (; n<16; n+=sizeof(size_t)) { | 142 | for (; n < 16; n += sizeof(size_t)) { |
136 | size_t t = *(size_t*)(in+n); | 143 | size_t t = *(size_t *)(in + n); |
137 | *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t; | 144 | *(size_t *)(out + n) = *(size_t *)(ivec + |
138 | *(size_t*)(ivec+n) = t; | 145 | n) ^ t; |
139 | } | 146 | *(size_t *)(ivec + n) = t; |
140 | len -= 16; | 147 | } |
141 | out += 16; | 148 | len -= 16; |
142 | in += 16; | 149 | out += 16; |
143 | n = 0; | 150 | in += 16; |
144 | } | 151 | n = 0; |
145 | if (len) { | 152 | } |
146 | (*block)(ivec, ivec, key); | 153 | if (len) { |
147 | while (len--) { | 154 | (*block)(ivec, ivec, key); |
148 | unsigned char c; | 155 | while (len--) { |
149 | out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c; | 156 | unsigned char c; |
150 | ++n; | 157 | out[n] = ivec[n] ^ (c = in[n]); |
151 | } | 158 | ivec[n] = c; |
152 | } | 159 | ++n; |
153 | *num = n; | 160 | } |
154 | return; | 161 | } |
155 | } while (0); | 162 | *num = n; |
163 | return; | ||
164 | } while (0); | ||
156 | /* the rest would be commonly eliminated by x86* compiler */ | 165 | /* the rest would be commonly eliminated by x86* compiler */ |
157 | #endif | 166 | #endif |
158 | while (l<len) { | 167 | while (l < len) { |
159 | unsigned char c; | 168 | unsigned char c; |
160 | if (n == 0) { | 169 | if (n == 0) { |
161 | (*block)(ivec, ivec, key); | 170 | (*block)(ivec, ivec, key); |
171 | } | ||
172 | out[l] = ivec[n] ^ (c = in[l]); | ||
173 | ivec[n] = c; | ||
174 | ++l; | ||
175 | n = (n + 1) % 16; | ||
162 | } | 176 | } |
163 | out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c; | 177 | *num = n; |
164 | ++l; | ||
165 | n = (n+1) % 16; | ||
166 | } | 178 | } |
167 | *num=n; | ||
168 | } | ||
169 | } | 179 | } |
170 | 180 | ||
171 | /* This expects a single block of size nbits for both in and out. Note that | 181 | /* This expects a single block of size nbits for both in and out. Note that |
172 | it corrupts any extra bits in the last byte of out */ | 182 | it corrupts any extra bits in the last byte of out */ |
173 | static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out, | 183 | static void |
174 | int nbits,const void *key, | 184 | cfbr_encrypt_block(const unsigned char *in, unsigned char *out, |
175 | unsigned char ivec[16],int enc, | 185 | int nbits, const void *key, |
176 | block128_f block) | 186 | unsigned char ivec[16], int enc, |
187 | block128_f block) | ||
177 | { | 188 | { |
178 | int n,rem,num; | 189 | int n, rem, num; |
179 | unsigned char ovec[16*2 + 1]; /* +1 because we dererefence (but don't use) one byte off the end */ | 190 | unsigned char ovec[16*2 + 1]; /* +1 because we dererefence (but don't use) one byte off the end */ |
180 | 191 | ||
181 | if (nbits<=0 || nbits>128) return; | 192 | if (nbits <= 0 || nbits > 128) |
193 | return; | ||
182 | 194 | ||
183 | /* fill in the first half of the new IV with the current IV */ | 195 | /* fill in the first half of the new IV with the current IV */ |
184 | memcpy(ovec,ivec,16); | 196 | memcpy(ovec, ivec, 16); |
185 | /* construct the new IV */ | 197 | /* construct the new IV */ |
186 | (*block)(ivec,ivec,key); | 198 | (*block)(ivec, ivec, key); |
187 | num = (nbits+7)/8; | 199 | num = (nbits + 7)/8; |
188 | if (enc) /* encrypt the input */ | 200 | if (enc) /* encrypt the input */ |
189 | for(n=0 ; n < num ; ++n) | 201 | for (n = 0; n < num; ++n) |
190 | out[n] = (ovec[16+n] = in[n] ^ ivec[n]); | 202 | out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); |
191 | else /* decrypt the input */ | 203 | else /* decrypt the input */ |
192 | for(n=0 ; n < num ; ++n) | 204 | for (n = 0; n < num; ++n) |
193 | out[n] = (ovec[16+n] = in[n]) ^ ivec[n]; | 205 | out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; |
194 | /* shift ovec left... */ | 206 | /* shift ovec left... */ |
195 | rem = nbits%8; | 207 | rem = nbits % 8; |
196 | num = nbits/8; | 208 | num = nbits/8; |
197 | if(rem==0) | 209 | if (rem == 0) |
198 | memcpy(ivec,ovec+num,16); | 210 | memcpy(ivec, ovec + num, 16); |
199 | else | 211 | else |
200 | for(n=0 ; n < 16 ; ++n) | 212 | for (n = 0; n < 16; ++n) |
201 | ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem); | 213 | ivec[n] = ovec[n + num] << rem | |
214 | ovec[n + num + 1] >> (8 - rem); | ||
202 | 215 | ||
203 | /* it is not necessary to cleanse ovec, since the IV is not secret */ | 216 | /* it is not necessary to cleanse ovec, since the IV is not secret */ |
204 | } | 217 | } |
205 | 218 | ||
206 | /* N.B. This expects the input to be packed, MS bit first */ | 219 | /* N.B. This expects the input to be packed, MS bit first */ |
207 | void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, | 220 | void |
208 | size_t bits, const void *key, | 221 | CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, |
209 | unsigned char ivec[16], int *num, | 222 | size_t bits, const void *key, |
210 | int enc, block128_f block) | 223 | unsigned char ivec[16], int *num, |
224 | int enc, block128_f block) | ||
211 | { | 225 | { |
212 | size_t n; | 226 | size_t n; |
213 | unsigned char c[1],d[1]; | 227 | unsigned char c[1], d[1]; |
214 | 228 | ||
215 | for(n=0 ; n<bits ; ++n) | 229 | for (n = 0; n < bits; ++n) |
216 | { | 230 | { |
217 | c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; | 231 | c[0] = (in[n/8] & (1 << (7 - n % 8))) ? 0x80 : 0; |
218 | cfbr_encrypt_block(c,d,1,key,ivec,enc,block); | 232 | cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); |
219 | out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) | | 233 | out[n/8] = (out[n/8] & ~(1 << (unsigned int)(7 - n % 8))) | |
220 | ((d[0]&0x80) >> (unsigned int)(n%8)); | 234 | ((d[0] & 0x80) >> (unsigned int)(n % 8)); |
221 | } | 235 | } |
222 | } | 236 | } |
223 | 237 | ||
224 | void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, | 238 | void |
225 | size_t length, const void *key, | 239 | CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, |
226 | unsigned char ivec[16], int *num, | 240 | size_t length, const void *key, |
227 | int enc, block128_f block) | 241 | unsigned char ivec[16], int *num, |
242 | int enc, block128_f block) | ||
228 | { | 243 | { |
229 | size_t n; | 244 | size_t n; |
230 | 245 | ||
231 | for(n=0 ; n<length ; ++n) | 246 | for (n = 0; n < length; ++n) |
232 | cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block); | 247 | cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); |
233 | } | 248 | } |
234 | |||