158
/* This expects a single block of size nbits for both in and out. Note that
159
it corrupts any extra bits in the last byte of out */
160
/* Untested, once it is working, it will be optimised */
161
void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
162
const int nbits,const AES_KEY *key,
163
unsigned char *ivec,const int enc)
166
unsigned char ovec[AES_BLOCK_SIZE*2];
168
assert(in && out && key && ivec);
171
/* construct the new IV */
172
AES_encrypt(ivec,ovec,key);
173
/* encrypt the input */
174
for(n=0 ; n < (nbits+7)/8 ; ++n)
175
out[n]=in[n]^ovec[n];
176
/* fill in the first half of the new IV with the current IV */
177
memcpy(ovec,ivec,AES_BLOCK_SIZE);
178
/* and put the ciphertext in the second half */
179
memcpy(ovec+AES_BLOCK_SIZE,out,(nbits+7)/8);
180
/* shift ovec left most of the bits... */
181
memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0));
182
/* now the remaining bits */
184
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
187
ovec[n]|=ovec[n+1]>>(8-nbits%8);
189
/* finally, move it back into place */
190
memcpy(ivec,ovec,AES_BLOCK_SIZE);
194
/* construct the new IV in the first half of ovec */
195
AES_encrypt(ivec,ovec,key);
196
/* decrypt the input */
197
for(n=0 ; n < (nbits+7)/8 ; ++n)
198
out[n]=in[n]^ovec[n];
199
/* fill in the first half of the new IV with the current IV */
200
memcpy(ovec,ivec,AES_BLOCK_SIZE);
201
/* append the ciphertext */
202
memcpy(ovec+AES_BLOCK_SIZE,in,(nbits+7)/8);
203
/* shift ovec left most of the bits... */
204
memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0));
205
/* now the remaining bits */
207
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
210
ovec[n]|=ovec[n+1]>>(8-nbits%8);
212
/* finally, move it back into place */
213
memcpy(ivec,ovec,AES_BLOCK_SIZE);
215
/* it is not necessary to cleanse ovec, since the IV is not secret */
218
/* N.B. This expects the input to be packed, MS bit first */
219
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
220
const unsigned long length, const AES_KEY *key,
221
unsigned char *ivec, int *num, const int enc)
224
unsigned char c[1],d[1];
226
assert(in && out && key && ivec && num);
229
memset(out,0,(length+7)/8);
230
for(n=0 ; n < length ; ++n)
232
c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
233
AES_cfbr_encrypt_block(c,d,1,key,ivec,enc);
234
out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
238
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
239
const unsigned long length, const AES_KEY *key,
240
unsigned char *ivec, int *num, const int enc)
244
assert(in && out && key && ivec && num);
247
for(n=0 ; n < length ; ++n)
248
AES_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);