~ubuntu-branches/ubuntu/utopic/openssl/utopic

« 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-04-02 13:19:19 UTC
  • mfrom: (1.2.1 upstream) (11.2.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 55.
  • Revision ID: james.westby@ubuntu.com-20110402131919-anszuslper64ey9e
Tags: 1.0.0d-1
* New upstream version
  - Fixes CVE-2011-0014
* Make libssl-doc Replaces/Breaks with old libssl-dev packages
  (Closes: #607609)
* Only export the symbols we should, instead of all.
* Add symbol file.
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
66
66
#endif
67
67
#include "evp_locl.h"
68
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
69
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
78
70
 
 
71
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
 
72
        {
 
73
        memset(ctx,0,sizeof(EVP_CIPHER_CTX));
 
74
        /* ctx->cipher=NULL; */
 
75
        }
 
76
 
79
77
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
80
78
        {
81
79
        EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
92
90
        return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
93
91
        }
94
92
 
 
93
int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
 
94
             const unsigned char *key, const unsigned char *iv, int enc)
 
95
        {
 
96
        if (enc == -1)
 
97
                enc = ctx->encrypt;
 
98
        else
 
99
                {
 
100
                if (enc)
 
101
                        enc = 1;
 
102
                ctx->encrypt = enc;
 
103
                }
 
104
#ifndef OPENSSL_NO_ENGINE
 
105
        /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
 
106
         * so this context may already have an ENGINE! Try to avoid releasing
 
107
         * the previous handle, re-querying for an ENGINE, and having a
 
108
         * reinitialisation, when it may all be unecessary. */
 
109
        if (ctx->engine && ctx->cipher && (!cipher ||
 
110
                        (cipher && (cipher->nid == ctx->cipher->nid))))
 
111
                goto skip_to_init;
 
112
#endif
 
113
        if (cipher)
 
114
                {
 
115
                /* Ensure a context left lying around from last time is cleared
 
116
                 * (the previous check attempted to avoid this if the same
 
117
                 * ENGINE and EVP_CIPHER could be used). */
 
118
                EVP_CIPHER_CTX_cleanup(ctx);
 
119
 
 
120
                /* Restore encrypt field: it is zeroed by cleanup */
 
121
                ctx->encrypt = enc;
 
122
#ifndef OPENSSL_NO_ENGINE
 
123
                if(impl)
 
124
                        {
 
125
                        if (!ENGINE_init(impl))
 
126
                                {
 
127
                                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
 
128
                                return 0;
 
129
                                }
 
130
                        }
 
131
                else
 
132
                        /* Ask if an ENGINE is reserved for this job */
 
133
                        impl = ENGINE_get_cipher_engine(cipher->nid);
 
134
                if(impl)
 
135
                        {
 
136
                        /* There's an ENGINE for this job ... (apparently) */
 
137
                        const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
 
138
                        if(!c)
 
139
                                {
 
140
                                /* One positive side-effect of US's export
 
141
                                 * control history, is that we should at least
 
142
                                 * be able to avoid using US mispellings of
 
143
                                 * "initialisation"? */
 
144
                                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
 
145
                                return 0;
 
146
                                }
 
147
                        /* We'll use the ENGINE's private cipher definition */
 
148
                        cipher = c;
 
149
                        /* Store the ENGINE functional reference so we know
 
150
                         * 'cipher' came from an ENGINE and we need to release
 
151
                         * it when done. */
 
152
                        ctx->engine = impl;
 
153
                        }
 
154
                else
 
155
                        ctx->engine = NULL;
 
156
#endif
 
157
 
 
158
                ctx->cipher=cipher;
 
159
                if (ctx->cipher->ctx_size)
 
160
                        {
 
161
                        ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
 
162
                        if (!ctx->cipher_data)
 
163
                                {
 
164
                                EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
 
165
                                return 0;
 
166
                                }
 
167
                        }
 
168
                else
 
169
                        {
 
170
                        ctx->cipher_data = NULL;
 
171
                        }
 
172
                ctx->key_len = cipher->key_len;
 
173
                ctx->flags = 0;
 
174
                if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
 
175
                        {
 
176
                        if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
 
177
                                {
 
178
                                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
 
179
                                return 0;
 
180
                                }
 
181
                        }
 
182
                }
 
183
        else if(!ctx->cipher)
 
184
                {
 
185
                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
 
186
                return 0;
 
187
                }
 
188
#ifndef OPENSSL_NO_ENGINE
 
189
skip_to_init:
 
190
#endif
 
191
        /* we assume block size is a power of 2 in *cryptUpdate */
 
192
        OPENSSL_assert(ctx->cipher->block_size == 1
 
193
            || ctx->cipher->block_size == 8
 
194
            || ctx->cipher->block_size == 16);
 
195
 
 
196
        if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
 
197
                switch(EVP_CIPHER_CTX_mode(ctx)) {
 
198
 
 
199
                        case EVP_CIPH_STREAM_CIPHER:
 
200
                        case EVP_CIPH_ECB_MODE:
 
201
                        break;
 
202
 
 
203
                        case EVP_CIPH_CFB_MODE:
 
204
                        case EVP_CIPH_OFB_MODE:
 
205
 
 
206
                        ctx->num = 0;
 
207
                        /* fall-through */
 
208
 
 
209
                        case EVP_CIPH_CBC_MODE:
 
210
 
 
211
                        OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
 
212
                                        (int)sizeof(ctx->iv));
 
213
                        if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
 
214
                        memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
 
215
                        break;
 
216
 
 
217
                        default:
 
218
                        return 0;
 
219
                        break;
 
220
                }
 
221
        }
 
222
 
 
223
        if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
 
224
                if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
 
225
        }
 
226
        ctx->buf_len=0;
 
227
        ctx->final_used=0;
 
228
        ctx->block_mask=ctx->cipher->block_size-1;
 
229
        return 1;
 
230
        }
 
231
 
95
232
int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
96
233
             const unsigned char *in, int inl)
97
234
        {
151
288
 
152
289
        if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
153
290
                {
154
 
                if(M_do_cipher(ctx,out,in,inl))
 
291
                if(ctx->cipher->do_cipher(ctx,out,in,inl))
155
292
                        {
156
293
                        *outl=inl;
157
294
                        return 1;
178
315
                        {
179
316
                        j=bl-i;
180
317
                        memcpy(&(ctx->buf[i]),in,j);
181
 
                        if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
 
318
                        if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
182
319
                        inl-=j;
183
320
                        in+=j;
184
321
                        out+=bl;
191
328
        inl-=i;
192
329
        if (inl > 0)
193
330
                {
194
 
                if(!M_do_cipher(ctx,out,in,inl)) return 0;
 
331
                if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
195
332
                *outl+=inl;
196
333
                }
197
334
 
235
372
        n=b-bl;
236
373
        for (i=bl; i<b; i++)
237
374
                ctx->buf[i]=n;
238
 
        ret=M_do_cipher(ctx,out,ctx->buf,b);
 
375
        ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
239
376
 
240
377
 
241
378
        if(ret)
357
494
                }
358
495
        }
359
496
 
 
497
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
 
498
        {
 
499
        if (c->cipher != NULL)
 
500
                {
 
501
                if(c->cipher->cleanup && !c->cipher->cleanup(c))
 
502
                        return 0;
 
503
                /* Cleanse cipher context data */
 
504
                if (c->cipher_data)
 
505
                        OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
 
506
                }
 
507
        if (c->cipher_data)
 
508
                OPENSSL_free(c->cipher_data);
 
509
#ifndef OPENSSL_NO_ENGINE
 
510
        if (c->engine)
 
511
                /* The EVP_CIPHER we used belongs to an ENGINE, release the
 
512
                 * functional reference we held for this reason. */
 
513
                ENGINE_finish(c->engine);
 
514
#endif
 
515
        memset(c,0,sizeof(EVP_CIPHER_CTX));
 
516
        return 1;
 
517
        }
 
518
 
360
519
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
361
520
        {
362
521
        if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
378
537
        return 1;
379
538
        }
380
539
 
 
540
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
 
541
{
 
542
        int ret;
 
543
        if(!ctx->cipher) {
 
544
                EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
 
545
                return 0;
 
546
        }
 
547
 
 
548
        if(!ctx->cipher->ctrl) {
 
549
                EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
 
550
                return 0;
 
551
        }
 
552
 
 
553
        ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
 
554
        if(ret == -1) {
 
555
                EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
 
556
                return 0;
 
557
        }
 
558
        return ret;
 
559
}
 
560
 
381
561
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
382
562
        {
383
563
        if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
387
567
        return 1;
388
568
        }
389
569
 
 
570
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
 
571
        {
 
572
        if ((in == NULL) || (in->cipher == NULL))
 
573
                {
 
574
                EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
 
575
                return 0;
 
576
                }
390
577
#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;
 
578
        /* Make sure it's safe to copy a cipher context using an ENGINE */
 
579
        if (in->engine && !ENGINE_init(in->engine))
 
580
                {
 
581
                EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
 
582
                return 0;
 
583
                }
 
584
#endif
 
585
 
 
586
        EVP_CIPHER_CTX_cleanup(out);
 
587
        memcpy(out,in,sizeof *out);
 
588
 
 
589
        if (in->cipher_data && in->cipher->ctx_size)
 
590
                {
 
591
                out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
 
592
                if (!out->cipher_data)
 
593
                        {
 
594
                        EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
 
595
                        return 0;
 
596
                        }
 
597
                memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
 
598
                }
 
599
 
 
600
        if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
 
601
                return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
429
602
        return 1;
430
603
        }
431
604
 
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