summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp/evp_enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/evp/evp_enc.c')
-rw-r--r--src/lib/libcrypto/evp/evp_enc.c290
1 files changed, 229 insertions, 61 deletions
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c
index e2687f9879..d28a7d266e 100644
--- a/src/lib/libcrypto/evp/evp_enc.c
+++ b/src/lib/libcrypto/evp/evp_enc.c
@@ -60,8 +60,11 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/evp.h> 61#include <openssl/evp.h>
62#include <openssl/err.h> 62#include <openssl/err.h>
63#include <openssl/engine.h>
63#include "evp_locl.h" 64#include "evp_locl.h"
64 65
66#include <assert.h>
67
65const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT; 68const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT;
66 69
67void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) 70void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
@@ -70,23 +73,97 @@ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
70 /* ctx->cipher=NULL; */ 73 /* ctx->cipher=NULL; */
71 } 74 }
72 75
76
73int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 77int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
74 unsigned char *key, unsigned char *iv, int enc) 78 const unsigned char *key, const unsigned char *iv, int enc)
75 { 79 {
76 if(enc && (enc != -1)) enc = 1; 80 if (cipher)
77 if (cipher) { 81 EVP_CIPHER_CTX_init(ctx);
82 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
83 }
84
85int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
86 const unsigned char *key, const unsigned char *iv, int enc)
87 {
88 if (enc == -1)
89 enc = ctx->encrypt;
90 else
91 {
92 if (enc)
93 enc = 1;
94 ctx->encrypt = enc;
95 }
96 /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
97 * so this context may already have an ENGINE! Try to avoid releasing
98 * the previous handle, re-querying for an ENGINE, and having a
99 * reinitialisation, when it may all be unecessary. */
100 if (ctx->engine && ctx->cipher && (!cipher ||
101 (cipher && (cipher->nid == ctx->cipher->nid))))
102 goto skip_to_init;
103 if (cipher)
104 {
105 /* Ensure an ENGINE left lying around from last time is cleared
106 * (the previous check attempted to avoid this if the same
107 * ENGINE and EVP_CIPHER could be used). */
108 if(ctx->engine)
109 ENGINE_finish(ctx->engine);
110 if(impl)
111 {
112 if (!ENGINE_init(impl))
113 {
114 EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
115 return 0;
116 }
117 }
118 else
119 /* Ask if an ENGINE is reserved for this job */
120 impl = ENGINE_get_cipher_engine(cipher->nid);
121 if(impl)
122 {
123 /* There's an ENGINE for this job ... (apparently) */
124 const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
125 if(!c)
126 {
127 /* One positive side-effect of US's export
128 * control history, is that we should at least
129 * be able to avoid using US mispellings of
130 * "initialisation"? */
131 EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
132 return 0;
133 }
134 /* We'll use the ENGINE's private cipher definition */
135 cipher = c;
136 /* Store the ENGINE functional reference so we know
137 * 'cipher' came from an ENGINE and we need to release
138 * it when done. */
139 ctx->engine = impl;
140 }
141 else
142 ctx->engine = NULL;
78 ctx->cipher=cipher; 143 ctx->cipher=cipher;
144 ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
79 ctx->key_len = cipher->key_len; 145 ctx->key_len = cipher->key_len;
80 if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { 146 ctx->flags = 0;
81 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { 147 if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
148 {
149 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
150 {
82 EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR); 151 EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
83 return 0; 152 return 0;
153 }
84 } 154 }
85 } 155 }
86 } else if(!ctx->cipher) { 156 else if(!ctx->cipher)
157 {
87 EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET); 158 EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);
88 return 0; 159 return 0;
89 } 160 }
161skip_to_init:
162 /* we assume block size is a power of 2 in *cryptUpdate */
163 assert(ctx->cipher->block_size == 1
164 || ctx->cipher->block_size == 8
165 || ctx->cipher->block_size == 16);
166
90 if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { 167 if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
91 switch(EVP_CIPHER_CTX_mode(ctx)) { 168 switch(EVP_CIPHER_CTX_mode(ctx)) {
92 169
@@ -114,68 +191,101 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
114 if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { 191 if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
115 if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; 192 if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
116 } 193 }
117 if(enc != -1) ctx->encrypt=enc;
118 ctx->buf_len=0; 194 ctx->buf_len=0;
195 ctx->final_used=0;
196 ctx->block_mask=ctx->cipher->block_size-1;
119 return 1; 197 return 1;
120 } 198 }
121 199
122int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 200int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
123 unsigned char *in, int inl) 201 const unsigned char *in, int inl)
124 { 202 {
125 if (ctx->encrypt) 203 if (ctx->encrypt)
126 return EVP_EncryptUpdate(ctx,out,outl,in,inl); 204 return EVP_EncryptUpdate(ctx,out,outl,in,inl);
127 else return EVP_DecryptUpdate(ctx,out,outl,in,inl); 205 else return EVP_DecryptUpdate(ctx,out,outl,in,inl);
128 } 206 }
129 207
208int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
209 {
210 if (ctx->encrypt)
211 return EVP_EncryptFinal_ex(ctx,out,outl);
212 else return EVP_DecryptFinal_ex(ctx,out,outl);
213 }
214
130int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 215int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
131 { 216 {
132 if (ctx->encrypt) 217 if (ctx->encrypt)
133 return EVP_EncryptFinal(ctx,out,outl); 218 return EVP_EncryptFinal(ctx,out,outl);
134 else return(EVP_DecryptFinal(ctx,out,outl)); 219 else return EVP_DecryptFinal(ctx,out,outl);
135 } 220 }
136 221
137int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 222int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
138 unsigned char *key, unsigned char *iv) 223 const unsigned char *key, const unsigned char *iv)
139 { 224 {
140 return EVP_CipherInit(ctx, cipher, key, iv, 1); 225 return EVP_CipherInit(ctx, cipher, key, iv, 1);
141 } 226 }
142 227
228int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
229 const unsigned char *key, const unsigned char *iv)
230 {
231 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
232 }
233
143int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 234int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
144 unsigned char *key, unsigned char *iv) 235 const unsigned char *key, const unsigned char *iv)
145 { 236 {
146 return EVP_CipherInit(ctx, cipher, key, iv, 0); 237 return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0);
147 } 238 }
148 239
240int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
241 const unsigned char *key, const unsigned char *iv)
242 {
243 return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
244 }
149 245
150int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 246int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
151 unsigned char *in, int inl) 247 const unsigned char *in, int inl)
152 { 248 {
153 int i,j,bl; 249 int i,j,bl;
154 250
251 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
252 {
253 if(ctx->cipher->do_cipher(ctx,out,in,inl))
254 {
255 *outl=inl;
256 return 1;
257 }
258 else
259 {
260 *outl=0;
261 return 0;
262 }
263 }
155 i=ctx->buf_len; 264 i=ctx->buf_len;
156 bl=ctx->cipher->block_size; 265 bl=ctx->cipher->block_size;
157 *outl=0;
158 if ((inl == 0) && (i != bl)) return 1;
159 if (i != 0) 266 if (i != 0)
160 { 267 {
161 if (i+inl < bl) 268 if (i+inl < bl)
162 { 269 {
163 memcpy(&(ctx->buf[i]),in,inl); 270 memcpy(&(ctx->buf[i]),in,inl);
164 ctx->buf_len+=inl; 271 ctx->buf_len+=inl;
272 *outl=0;
165 return 1; 273 return 1;
166 } 274 }
167 else 275 else
168 { 276 {
169 j=bl-i; 277 j=bl-i;
170 if (j != 0) memcpy(&(ctx->buf[i]),in,j); 278 memcpy(&(ctx->buf[i]),in,j);
171 if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; 279 if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
172 inl-=j; 280 inl-=j;
173 in+=j; 281 in+=j;
174 out+=bl; 282 out+=bl;
175 *outl+=bl; 283 *outl=bl;
176 } 284 }
177 } 285 }
178 i=inl%bl; /* how much is left */ 286 else
287 *outl = 0;
288 i=inl&(bl-1);
179 inl-=i; 289 inl-=i;
180 if (inl > 0) 290 if (inl > 0)
181 { 291 {
@@ -191,107 +301,153 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
191 301
192int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 302int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
193 { 303 {
194 int i,n,b,bl; 304 int ret;
305 ret = EVP_EncryptFinal_ex(ctx, out, outl);
306 EVP_CIPHER_CTX_cleanup(ctx);
307 return ret;
308 }
309
310int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
311 {
312 int i,n,b,bl,ret;
195 313
196 b=ctx->cipher->block_size; 314 b=ctx->cipher->block_size;
197 if (b == 1) 315 if (b == 1)
198 { 316 {
317 EVP_CIPHER_CTX_cleanup(ctx);
199 *outl=0; 318 *outl=0;
200 return 1; 319 return 1;
201 } 320 }
202 bl=ctx->buf_len; 321 bl=ctx->buf_len;
322 if (ctx->flags & EVP_CIPH_NO_PADDING)
323 {
324 EVP_CIPHER_CTX_cleanup(ctx);
325 if(bl)
326 {
327 EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
328 return 0;
329 }
330 *outl = 0;
331 return 1;
332 }
333
203 n=b-bl; 334 n=b-bl;
204 for (i=bl; i<b; i++) 335 for (i=bl; i<b; i++)
205 ctx->buf[i]=n; 336 ctx->buf[i]=n;
206 if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,b)) return 0; 337 ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
207 *outl=b; 338
208 return 1; 339 EVP_CIPHER_CTX_cleanup(ctx);
340
341 if(ret)
342 *outl=b;
343
344 return ret;
209 } 345 }
210 346
211int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 347int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
212 unsigned char *in, int inl) 348 const unsigned char *in, int inl)
213 { 349 {
214 int b,bl,n; 350 int b, fix_len;
215 int keep_last=0;
216 351
217 *outl=0; 352 if (inl == 0)
218 if (inl == 0) return 1; 353 {
354 *outl=0;
355 return 1;
356 }
357
358 if (ctx->flags & EVP_CIPH_NO_PADDING)
359 return EVP_EncryptUpdate(ctx, out, outl, in, inl);
219 360
220 b=ctx->cipher->block_size; 361 b=ctx->cipher->block_size;
221 if (b > 1) 362
363 if(ctx->final_used)
222 { 364 {
223 /* Is the input a multiple of the block size? */ 365 memcpy(out,ctx->final,b);
224 bl=ctx->buf_len; 366 out+=b;
225 n=inl+bl; 367 fix_len = 1;
226 if (n%b == 0)
227 {
228 if (inl < b) /* must be 'just one' buff */
229 {
230 memcpy(&(ctx->buf[bl]),in,inl);
231 ctx->buf_len=b;
232 *outl=0;
233 return 1;
234 }
235 keep_last=1;
236 inl-=b; /* don't do the last block */
237 }
238 } 368 }
239 if(!EVP_EncryptUpdate(ctx,out,outl,in,inl)) return 0; 369 else
370 fix_len = 0;
371
372
373 if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
374 return 0;
240 375
241 /* if we have 'decrypted' a multiple of block size, make sure 376 /* if we have 'decrypted' a multiple of block size, make sure
242 * we have a copy of this last block */ 377 * we have a copy of this last block */
243 if (keep_last) 378 if (b > 1 && !ctx->buf_len)
244 { 379 {
245 memcpy(&(ctx->buf[0]),&(in[inl]),b); 380 *outl-=b;
246#ifdef DEBUG 381 ctx->final_used=1;
247 if (ctx->buf_len != 0) 382 memcpy(ctx->final,&out[*outl],b);
248 {
249 abort();
250 }
251#endif
252 ctx->buf_len=b;
253 } 383 }
384 else
385 ctx->final_used = 0;
386
387 if (fix_len)
388 *outl += b;
389
254 return 1; 390 return 1;
255 } 391 }
256 392
257int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) 393int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
258 { 394 {
395 int ret;
396 ret = EVP_DecryptFinal_ex(ctx, out, outl);
397 EVP_CIPHER_CTX_cleanup(ctx);
398 return ret;
399 }
400
401int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
402 {
259 int i,b; 403 int i,b;
260 int n; 404 int n;
261 405
262 *outl=0; 406 *outl=0;
263 b=ctx->cipher->block_size; 407 b=ctx->cipher->block_size;
408 if (ctx->flags & EVP_CIPH_NO_PADDING)
409 {
410 EVP_CIPHER_CTX_cleanup(ctx);
411 if(ctx->buf_len)
412 {
413 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
414 return 0;
415 }
416 *outl = 0;
417 return 1;
418 }
264 if (b > 1) 419 if (b > 1)
265 { 420 {
266 if (ctx->buf_len != b) 421 if (ctx->buf_len || !ctx->final_used)
267 { 422 {
423 EVP_CIPHER_CTX_cleanup(ctx);
268 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH); 424 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
269 return(0); 425 return(0);
270 } 426 }
271 if(!EVP_EncryptUpdate(ctx,ctx->buf,&n,ctx->buf,0)) return 0; 427 n=ctx->final[b-1];
272 if (n != b)
273 return(0);
274 n=ctx->buf[b-1];
275 if (n > b) 428 if (n > b)
276 { 429 {
430 EVP_CIPHER_CTX_cleanup(ctx);
277 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); 431 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
278 return(0); 432 return(0);
279 } 433 }
280 for (i=0; i<n; i++) 434 for (i=0; i<n; i++)
281 { 435 {
282 if (ctx->buf[--b] != n) 436 if (ctx->final[--b] != n)
283 { 437 {
438 EVP_CIPHER_CTX_cleanup(ctx);
284 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT); 439 EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
285 return(0); 440 return(0);
286 } 441 }
287 } 442 }
288 n=ctx->cipher->block_size-n; 443 n=ctx->cipher->block_size-n;
289 for (i=0; i<n; i++) 444 for (i=0; i<n; i++)
290 out[i]=ctx->buf[i]; 445 out[i]=ctx->final[i];
291 *outl=n; 446 *outl=n;
292 } 447 }
293 else 448 else
294 *outl=0; 449 *outl=0;
450 EVP_CIPHER_CTX_cleanup(ctx);
295 return(1); 451 return(1);
296 } 452 }
297 453
@@ -301,6 +457,11 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
301 { 457 {
302 if(!c->cipher->cleanup(c)) return 0; 458 if(!c->cipher->cleanup(c)) return 0;
303 } 459 }
460 OPENSSL_free(c->cipher_data);
461 if (c->engine)
462 /* The EVP_CIPHER we used belongs to an ENGINE, release the
463 * functional reference we held for this reason. */
464 ENGINE_finish(c->engine);
304 memset(c,0,sizeof(EVP_CIPHER_CTX)); 465 memset(c,0,sizeof(EVP_CIPHER_CTX));
305 return 1; 466 return 1;
306 } 467 }
@@ -319,6 +480,13 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
319 return 0; 480 return 0;
320 } 481 }
321 482
483int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
484 {
485 if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
486 else ctx->flags |= EVP_CIPH_NO_PADDING;
487 return 1;
488 }
489
322int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) 490int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
323{ 491{
324 int ret; 492 int ret;