summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/modes/cfb128.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/modes/cfb128.c')
-rw-r--r--src/lib/libcrypto/modes/cfb128.c268
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 */
66void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, 66void
67 size_t len, const void *key, 67CRYPTO_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 */
173static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out, 183static void
174 int nbits,const void *key, 184cfbr_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 */
207void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, 220void
208 size_t bits, const void *key, 221CRYPTO_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
224void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, 238void
225 size_t length, const void *key, 239CRYPTO_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