~ubuntu-branches/ubuntu/maverick/openssl/maverick

« back to all changes in this revision

Viewing changes to crypto/aes/aes_cfb.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-12-16 18:41:29 UTC
  • mto: (11.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20041216184129-z7xjkul57mh1jiha
Tags: upstream-0.9.7e
ImportĀ upstreamĀ versionĀ 0.9.7e

Show diffs side-by-side

added added

removed removed

Lines of Context:
155
155
        *num=n;
156
156
}
157
157
 
 
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)
 
164
    {
 
165
    int n;
 
166
    unsigned char ovec[AES_BLOCK_SIZE*2];
 
167
 
 
168
    assert(in && out && key && ivec);
 
169
    if(enc)
 
170
        {
 
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 */
 
183
        if(nbits%8 != 0)
 
184
            for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
 
185
                {
 
186
                ovec[n]<<=nbits%8;
 
187
                ovec[n]|=ovec[n+1]>>(8-nbits%8);
 
188
                }
 
189
        /* finally, move it back into place */
 
190
        memcpy(ivec,ovec,AES_BLOCK_SIZE);
 
191
        }
 
192
    else
 
193
        {
 
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 */
 
206
        if(nbits%8 != 0)
 
207
            for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
 
208
                {
 
209
                ovec[n]<<=nbits%8;
 
210
                ovec[n]|=ovec[n+1]>>(8-nbits%8);
 
211
                }
 
212
        /* finally, move it back into place */
 
213
        memcpy(ivec,ovec,AES_BLOCK_SIZE);
 
214
        }
 
215
    /* it is not necessary to cleanse ovec, since the IV is not secret */
 
216
    }
 
217
 
 
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)
 
222
    {
 
223
    unsigned int n;
 
224
    unsigned char c[1],d[1];
 
225
 
 
226
    assert(in && out && key && ivec && num);
 
227
    assert(*num == 0);
 
228
 
 
229
    memset(out,0,(length+7)/8);
 
230
    for(n=0 ; n < length ; ++n)
 
231
        {
 
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));
 
235
        }
 
236
    }
 
237
 
 
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)
 
241
    {
 
242
    unsigned int n;
 
243
 
 
244
    assert(in && out && key && ivec && num);
 
245
    assert(*num == 0);
 
246
 
 
247
    for(n=0 ; n < length ; ++n)
 
248
        AES_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);
 
249
    }
 
250