~ubuntu-branches/ubuntu/precise/openssl098/precise

« back to all changes in this revision

Viewing changes to crypto/evp/evp_enc.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2011-03-23 19:50:31 UTC
  • Revision ID: james.westby@ubuntu.com-20110323195031-6h9crj4bymhhr8b8
Tags: upstream-0.9.8o
ImportĀ upstreamĀ versionĀ 0.9.8o

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* crypto/evp/evp_enc.c */
 
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 
3
 * All rights reserved.
 
4
 *
 
5
 * This package is an SSL implementation written
 
6
 * by Eric Young (eay@cryptsoft.com).
 
7
 * The implementation was written so as to conform with Netscapes SSL.
 
8
 * 
 
9
 * This library is free for commercial and non-commercial use as long as
 
10
 * the following conditions are aheared to.  The following conditions
 
11
 * apply to all code found in this distribution, be it the RC4, RSA,
 
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 
13
 * included with this distribution is covered by the same copyright terms
 
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 
15
 * 
 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
 
17
 * the code are not to be removed.
 
18
 * If this package is used in a product, Eric Young should be given attribution
 
19
 * as the author of the parts of the library used.
 
20
 * This can be in the form of a textual message at program startup or
 
21
 * in documentation (online or textual) provided with the package.
 
22
 * 
 
23
 * Redistribution and use in source and binary forms, with or without
 
24
 * modification, are permitted provided that the following conditions
 
25
 * are met:
 
26
 * 1. Redistributions of source code must retain the copyright
 
27
 *    notice, this list of conditions and the following disclaimer.
 
28
 * 2. Redistributions in binary form must reproduce the above copyright
 
29
 *    notice, this list of conditions and the following disclaimer in the
 
30
 *    documentation and/or other materials provided with the distribution.
 
31
 * 3. All advertising materials mentioning features or use of this software
 
32
 *    must display the following acknowledgement:
 
33
 *    "This product includes cryptographic software written by
 
34
 *     Eric Young (eay@cryptsoft.com)"
 
35
 *    The word 'cryptographic' can be left out if the rouines from the library
 
36
 *    being used are not cryptographic related :-).
 
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 
38
 *    the apps directory (application code) you must include an acknowledgement:
 
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 
40
 * 
 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
51
 * SUCH DAMAGE.
 
52
 * 
 
53
 * The licence and distribution terms for any publically available version or
 
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 
55
 * copied and put under another distribution licence
 
56
 * [including the GNU Public Licence.]
 
57
 */
 
58
 
 
59
#include <stdio.h>
 
60
#include "cryptlib.h"
 
61
#include <openssl/evp.h>
 
62
#include <openssl/err.h>
 
63
#include <openssl/rand.h>
 
64
#ifndef OPENSSL_NO_ENGINE
 
65
#include <openssl/engine.h>
 
66
#endif
 
67
#include "evp_locl.h"
 
68
 
 
69
#ifdef OPENSSL_FIPS
 
70
        #define M_do_cipher(ctx, out, in, inl) \
 
71
                EVP_Cipher(ctx,out,in,inl)
 
72
#else
 
73
        #define M_do_cipher(ctx, out, in, inl) \
 
74
                ctx->cipher->do_cipher(ctx,out,in,inl)
 
75
#endif
 
76
 
 
77
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
 
78
 
 
79
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
 
80
        {
 
81
        EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
 
82
        if (ctx)
 
83
                EVP_CIPHER_CTX_init(ctx);
 
84
        return ctx;
 
85
        }
 
86
 
 
87
int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 
88
             const unsigned char *key, const unsigned char *iv, int enc)
 
89
        {
 
90
        if (cipher)
 
91
                EVP_CIPHER_CTX_init(ctx);
 
92
        return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
 
93
        }
 
94
 
 
95
int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 
96
             const unsigned char *in, int inl)
 
97
        {
 
98
        if (ctx->encrypt)
 
99
                return EVP_EncryptUpdate(ctx,out,outl,in,inl);
 
100
        else    return EVP_DecryptUpdate(ctx,out,outl,in,inl);
 
101
        }
 
102
 
 
103
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
104
        {
 
105
        if (ctx->encrypt)
 
106
                return EVP_EncryptFinal_ex(ctx,out,outl);
 
107
        else    return EVP_DecryptFinal_ex(ctx,out,outl);
 
108
        }
 
109
 
 
110
int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
111
        {
 
112
        if (ctx->encrypt)
 
113
                return EVP_EncryptFinal(ctx,out,outl);
 
114
        else    return EVP_DecryptFinal(ctx,out,outl);
 
115
        }
 
116
 
 
117
int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 
118
             const unsigned char *key, const unsigned char *iv)
 
119
        {
 
120
        return EVP_CipherInit(ctx, cipher, key, iv, 1);
 
121
        }
 
122
 
 
123
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
 
124
                const unsigned char *key, const unsigned char *iv)
 
125
        {
 
126
        return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
 
127
        }
 
128
 
 
129
int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 
130
             const unsigned char *key, const unsigned char *iv)
 
131
        {
 
132
        return EVP_CipherInit(ctx, cipher, key, iv, 0);
 
133
        }
 
134
 
 
135
int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
 
136
             const unsigned char *key, const unsigned char *iv)
 
137
        {
 
138
        return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
 
139
        }
 
140
 
 
141
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 
142
             const unsigned char *in, int inl)
 
143
        {
 
144
        int i,j,bl;
 
145
 
 
146
        if (inl <= 0)
 
147
                {
 
148
                *outl = 0;
 
149
                return inl == 0;
 
150
                }
 
151
 
 
152
        if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
 
153
                {
 
154
                if(M_do_cipher(ctx,out,in,inl))
 
155
                        {
 
156
                        *outl=inl;
 
157
                        return 1;
 
158
                        }
 
159
                else
 
160
                        {
 
161
                        *outl=0;
 
162
                        return 0;
 
163
                        }
 
164
                }
 
165
        i=ctx->buf_len;
 
166
        bl=ctx->cipher->block_size;
 
167
        OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
 
168
        if (i != 0)
 
169
                {
 
170
                if (i+inl < bl)
 
171
                        {
 
172
                        memcpy(&(ctx->buf[i]),in,inl);
 
173
                        ctx->buf_len+=inl;
 
174
                        *outl=0;
 
175
                        return 1;
 
176
                        }
 
177
                else
 
178
                        {
 
179
                        j=bl-i;
 
180
                        memcpy(&(ctx->buf[i]),in,j);
 
181
                        if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
 
182
                        inl-=j;
 
183
                        in+=j;
 
184
                        out+=bl;
 
185
                        *outl=bl;
 
186
                        }
 
187
                }
 
188
        else
 
189
                *outl = 0;
 
190
        i=inl&(bl-1);
 
191
        inl-=i;
 
192
        if (inl > 0)
 
193
                {
 
194
                if(!M_do_cipher(ctx,out,in,inl)) return 0;
 
195
                *outl+=inl;
 
196
                }
 
197
 
 
198
        if (i != 0)
 
199
                memcpy(ctx->buf,&(in[inl]),i);
 
200
        ctx->buf_len=i;
 
201
        return 1;
 
202
        }
 
203
 
 
204
int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
205
        {
 
206
        int ret;
 
207
        ret = EVP_EncryptFinal_ex(ctx, out, outl);
 
208
        return ret;
 
209
        }
 
210
 
 
211
int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
212
        {
 
213
        int n,ret;
 
214
        unsigned int i, b, bl;
 
215
 
 
216
        b=ctx->cipher->block_size;
 
217
        OPENSSL_assert(b <= sizeof ctx->buf);
 
218
        if (b == 1)
 
219
                {
 
220
                *outl=0;
 
221
                return 1;
 
222
                }
 
223
        bl=ctx->buf_len;
 
224
        if (ctx->flags & EVP_CIPH_NO_PADDING)
 
225
                {
 
226
                if(bl)
 
227
                        {
 
228
                        EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
 
229
                        return 0;
 
230
                        }
 
231
                *outl = 0;
 
232
                return 1;
 
233
                }
 
234
 
 
235
        n=b-bl;
 
236
        for (i=bl; i<b; i++)
 
237
                ctx->buf[i]=n;
 
238
        ret=M_do_cipher(ctx,out,ctx->buf,b);
 
239
 
 
240
 
 
241
        if(ret)
 
242
                *outl=b;
 
243
 
 
244
        return ret;
 
245
        }
 
246
 
 
247
int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 
248
             const unsigned char *in, int inl)
 
249
        {
 
250
        int fix_len;
 
251
        unsigned int b;
 
252
 
 
253
        if (inl <= 0)
 
254
                {
 
255
                *outl = 0;
 
256
                return inl == 0;
 
257
                }
 
258
 
 
259
        if (ctx->flags & EVP_CIPH_NO_PADDING)
 
260
                return EVP_EncryptUpdate(ctx, out, outl, in, inl);
 
261
 
 
262
        b=ctx->cipher->block_size;
 
263
        OPENSSL_assert(b <= sizeof ctx->final);
 
264
 
 
265
        if(ctx->final_used)
 
266
                {
 
267
                memcpy(out,ctx->final,b);
 
268
                out+=b;
 
269
                fix_len = 1;
 
270
                }
 
271
        else
 
272
                fix_len = 0;
 
273
 
 
274
 
 
275
        if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
 
276
                return 0;
 
277
 
 
278
        /* if we have 'decrypted' a multiple of block size, make sure
 
279
         * we have a copy of this last block */
 
280
        if (b > 1 && !ctx->buf_len)
 
281
                {
 
282
                *outl-=b;
 
283
                ctx->final_used=1;
 
284
                memcpy(ctx->final,&out[*outl],b);
 
285
                }
 
286
        else
 
287
                ctx->final_used = 0;
 
288
 
 
289
        if (fix_len)
 
290
                *outl += b;
 
291
                
 
292
        return 1;
 
293
        }
 
294
 
 
295
int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
296
        {
 
297
        int ret;
 
298
        ret = EVP_DecryptFinal_ex(ctx, out, outl);
 
299
        return ret;
 
300
        }
 
301
 
 
302
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
303
        {
 
304
        int i,n;
 
305
        unsigned int b;
 
306
 
 
307
        *outl=0;
 
308
        b=ctx->cipher->block_size;
 
309
        if (ctx->flags & EVP_CIPH_NO_PADDING)
 
310
                {
 
311
                if(ctx->buf_len)
 
312
                        {
 
313
                        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
 
314
                        return 0;
 
315
                        }
 
316
                *outl = 0;
 
317
                return 1;
 
318
                }
 
319
        if (b > 1)
 
320
                {
 
321
                if (ctx->buf_len || !ctx->final_used)
 
322
                        {
 
323
                        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
 
324
                        return(0);
 
325
                        }
 
326
                OPENSSL_assert(b <= sizeof ctx->final);
 
327
                n=ctx->final[b-1];
 
328
                if (n == 0 || n > (int)b)
 
329
                        {
 
330
                        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
 
331
                        return(0);
 
332
                        }
 
333
                for (i=0; i<n; i++)
 
334
                        {
 
335
                        if (ctx->final[--b] != n)
 
336
                                {
 
337
                                EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
 
338
                                return(0);
 
339
                                }
 
340
                        }
 
341
                n=ctx->cipher->block_size-n;
 
342
                for (i=0; i<n; i++)
 
343
                        out[i]=ctx->final[i];
 
344
                *outl=n;
 
345
                }
 
346
        else
 
347
                *outl=0;
 
348
        return(1);
 
349
        }
 
350
 
 
351
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
 
352
        {
 
353
        if (ctx)
 
354
                {
 
355
                EVP_CIPHER_CTX_cleanup(ctx);
 
356
                OPENSSL_free(ctx);
 
357
                }
 
358
        }
 
359
 
 
360
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
 
361
        {
 
362
        if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
 
363
                return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
 
364
        if(c->key_len == keylen) return 1;
 
365
        if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
 
366
                {
 
367
                c->key_len = keylen;
 
368
                return 1;
 
369
                }
 
370
        EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
 
371
        return 0;
 
372
        }
 
373
 
 
374
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
 
375
        {
 
376
        if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
 
377
        else ctx->flags |= EVP_CIPH_NO_PADDING;
 
378
        return 1;
 
379
        }
 
380
 
 
381
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
 
382
        {
 
383
        if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
 
384
                return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
 
385
        if (RAND_bytes(key, ctx->key_len) <= 0)
 
386
                return 0;
 
387
        return 1;
 
388
        }
 
389
 
 
390
#ifndef OPENSSL_NO_ENGINE
 
391
 
 
392
#ifdef OPENSSL_FIPS
 
393
 
 
394
static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
 
395
        {
 
396
        if(impl)
 
397
                {
 
398
                if (!ENGINE_init(impl))
 
399
                        {
 
400
                        EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
 
401
                        return 0;
 
402
                        }
 
403
                }
 
404
        else
 
405
                /* Ask if an ENGINE is reserved for this job */
 
406
                impl = ENGINE_get_cipher_engine((*pcipher)->nid);
 
407
        if(impl)
 
408
                {
 
409
                /* There's an ENGINE for this job ... (apparently) */
 
410
                const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
 
411
                if(!c)
 
412
                        {
 
413
                        /* One positive side-effect of US's export
 
414
                         * control history, is that we should at least
 
415
                         * be able to avoid using US mispellings of
 
416
                         * "initialisation"? */
 
417
                        EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
 
418
                        return 0;
 
419
                        }
 
420
                /* We'll use the ENGINE's private cipher definition */
 
421
                *pcipher = c;
 
422
                /* Store the ENGINE functional reference so we know
 
423
                 * 'cipher' came from an ENGINE and we need to release
 
424
                 * it when done. */
 
425
                ctx->engine = impl;
 
426
                }
 
427
        else
 
428
                ctx->engine = NULL;
 
429
        return 1;
 
430
        }
 
431
 
 
432
void int_EVP_CIPHER_init_engine_callbacks(void)
 
433
        {
 
434
        int_EVP_CIPHER_set_engine_callbacks(
 
435
                ENGINE_finish, do_evp_enc_engine_full);
 
436
        }
 
437
 
 
438
#endif
 
439
 
 
440
#endif