diff options
Diffstat (limited to 'src/lib/libcrypto/evp/bio_enc.c')
| -rw-r--r-- | src/lib/libcrypto/evp/bio_enc.c | 126 |
1 files changed, 66 insertions, 60 deletions
diff --git a/src/lib/libcrypto/evp/bio_enc.c b/src/lib/libcrypto/evp/bio_enc.c index 6c30ddfc54..64fb2353af 100644 --- a/src/lib/libcrypto/evp/bio_enc.c +++ b/src/lib/libcrypto/evp/bio_enc.c | |||
| @@ -59,28 +59,19 @@ | |||
| 59 | #include <stdio.h> | 59 | #include <stdio.h> |
| 60 | #include <errno.h> | 60 | #include <errno.h> |
| 61 | #include "cryptlib.h" | 61 | #include "cryptlib.h" |
| 62 | #include "buffer.h" | 62 | #include <openssl/buffer.h> |
| 63 | #include "evp.h" | 63 | #include <openssl/evp.h> |
| 64 | 64 | ||
| 65 | #ifndef NOPROTO | 65 | static int enc_write(BIO *h, const char *buf, int num); |
| 66 | static int enc_write(BIO *h,char *buf,int num); | 66 | static int enc_read(BIO *h, char *buf, int size); |
| 67 | static int enc_read(BIO *h,char *buf,int size); | 67 | /*static int enc_puts(BIO *h, const char *str); */ |
| 68 | /*static int enc_puts(BIO *h,char *str); */ | 68 | /*static int enc_gets(BIO *h, char *str, int size); */ |
| 69 | /*static int enc_gets(BIO *h,char *str,int size); */ | 69 | static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2); |
| 70 | static long enc_ctrl(BIO *h,int cmd,long arg1,char *arg2); | ||
| 71 | static int enc_new(BIO *h); | 70 | static int enc_new(BIO *h); |
| 72 | static int enc_free(BIO *data); | 71 | static int enc_free(BIO *data); |
| 73 | #else | 72 | static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps); |
| 74 | static int enc_write(); | ||
| 75 | static int enc_read(); | ||
| 76 | /*static int enc_puts(); */ | ||
| 77 | /*static int enc_gets(); */ | ||
| 78 | static long enc_ctrl(); | ||
| 79 | static int enc_new(); | ||
| 80 | static int enc_free(); | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #define ENC_BLOCK_SIZE (1024*4) | 73 | #define ENC_BLOCK_SIZE (1024*4) |
| 74 | #define BUF_OFFSET EVP_MAX_BLOCK_LENGTH | ||
| 84 | 75 | ||
| 85 | typedef struct enc_struct | 76 | typedef struct enc_struct |
| 86 | { | 77 | { |
| @@ -90,7 +81,10 @@ typedef struct enc_struct | |||
| 90 | int finished; | 81 | int finished; |
| 91 | int ok; /* bad decrypt */ | 82 | int ok; /* bad decrypt */ |
| 92 | EVP_CIPHER_CTX cipher; | 83 | EVP_CIPHER_CTX cipher; |
| 93 | char buf[ENC_BLOCK_SIZE+10]; | 84 | /* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate |
| 85 | * can return up to a block more data than is presented to it | ||
| 86 | */ | ||
| 87 | char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2]; | ||
| 94 | } BIO_ENC_CTX; | 88 | } BIO_ENC_CTX; |
| 95 | 89 | ||
| 96 | static BIO_METHOD methods_enc= | 90 | static BIO_METHOD methods_enc= |
| @@ -103,21 +97,21 @@ static BIO_METHOD methods_enc= | |||
| 103 | enc_ctrl, | 97 | enc_ctrl, |
| 104 | enc_new, | 98 | enc_new, |
| 105 | enc_free, | 99 | enc_free, |
| 100 | enc_callback_ctrl, | ||
| 106 | }; | 101 | }; |
| 107 | 102 | ||
| 108 | BIO_METHOD *BIO_f_cipher() | 103 | BIO_METHOD *BIO_f_cipher(void) |
| 109 | { | 104 | { |
| 110 | return(&methods_enc); | 105 | return(&methods_enc); |
| 111 | } | 106 | } |
| 112 | 107 | ||
| 113 | static int enc_new(bi) | 108 | static int enc_new(BIO *bi) |
| 114 | BIO *bi; | ||
| 115 | { | 109 | { |
| 116 | BIO_ENC_CTX *ctx; | 110 | BIO_ENC_CTX *ctx; |
| 117 | 111 | ||
| 118 | ctx=(BIO_ENC_CTX *)Malloc(sizeof(BIO_ENC_CTX)); | 112 | ctx=(BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX)); |
| 119 | EVP_CIPHER_CTX_init(&ctx->cipher); | ||
| 120 | if (ctx == NULL) return(0); | 113 | if (ctx == NULL) return(0); |
| 114 | EVP_CIPHER_CTX_init(&ctx->cipher); | ||
| 121 | 115 | ||
| 122 | ctx->buf_len=0; | 116 | ctx->buf_len=0; |
| 123 | ctx->buf_off=0; | 117 | ctx->buf_off=0; |
| @@ -131,8 +125,7 @@ BIO *bi; | |||
| 131 | return(1); | 125 | return(1); |
| 132 | } | 126 | } |
| 133 | 127 | ||
| 134 | static int enc_free(a) | 128 | static int enc_free(BIO *a) |
| 135 | BIO *a; | ||
| 136 | { | 129 | { |
| 137 | BIO_ENC_CTX *b; | 130 | BIO_ENC_CTX *b; |
| 138 | 131 | ||
| @@ -140,17 +133,14 @@ BIO *a; | |||
| 140 | b=(BIO_ENC_CTX *)a->ptr; | 133 | b=(BIO_ENC_CTX *)a->ptr; |
| 141 | EVP_CIPHER_CTX_cleanup(&(b->cipher)); | 134 | EVP_CIPHER_CTX_cleanup(&(b->cipher)); |
| 142 | memset(a->ptr,0,sizeof(BIO_ENC_CTX)); | 135 | memset(a->ptr,0,sizeof(BIO_ENC_CTX)); |
| 143 | Free(a->ptr); | 136 | OPENSSL_free(a->ptr); |
| 144 | a->ptr=NULL; | 137 | a->ptr=NULL; |
| 145 | a->init=0; | 138 | a->init=0; |
| 146 | a->flags=0; | 139 | a->flags=0; |
| 147 | return(1); | 140 | return(1); |
| 148 | } | 141 | } |
| 149 | 142 | ||
| 150 | static int enc_read(b,out,outl) | 143 | static int enc_read(BIO *b, char *out, int outl) |
| 151 | BIO *b; | ||
| 152 | char *out; | ||
| 153 | int outl; | ||
| 154 | { | 144 | { |
| 155 | int ret=0,i; | 145 | int ret=0,i; |
| 156 | BIO_ENC_CTX *ctx; | 146 | BIO_ENC_CTX *ctx; |
| @@ -184,9 +174,9 @@ int outl; | |||
| 184 | { | 174 | { |
| 185 | if (ctx->cont <= 0) break; | 175 | if (ctx->cont <= 0) break; |
| 186 | 176 | ||
| 187 | /* read in at offset 8, read the EVP_Cipher | 177 | /* read in at IV offset, read the EVP_Cipher |
| 188 | * documentation about why */ | 178 | * documentation about why */ |
| 189 | i=BIO_read(b->next_bio,&(ctx->buf[8]),ENC_BLOCK_SIZE); | 179 | i=BIO_read(b->next_bio,&(ctx->buf[BUF_OFFSET]),ENC_BLOCK_SIZE); |
| 190 | 180 | ||
| 191 | if (i <= 0) | 181 | if (i <= 0) |
| 192 | { | 182 | { |
| @@ -194,29 +184,37 @@ int outl; | |||
| 194 | if (!BIO_should_retry(b->next_bio)) | 184 | if (!BIO_should_retry(b->next_bio)) |
| 195 | { | 185 | { |
| 196 | ctx->cont=i; | 186 | ctx->cont=i; |
| 197 | i=EVP_CipherFinal(&(ctx->cipher), | 187 | i=EVP_CipherFinal_ex(&(ctx->cipher), |
| 198 | (unsigned char *)ctx->buf, | 188 | (unsigned char *)ctx->buf, |
| 199 | &(ctx->buf_len)); | 189 | &(ctx->buf_len)); |
| 200 | ctx->ok=i; | 190 | ctx->ok=i; |
| 201 | ctx->buf_off=0; | 191 | ctx->buf_off=0; |
| 202 | } | 192 | } |
| 203 | else | 193 | else |
| 194 | { | ||
| 204 | ret=(ret == 0)?i:ret; | 195 | ret=(ret == 0)?i:ret; |
| 205 | break; | 196 | break; |
| 197 | } | ||
| 206 | } | 198 | } |
| 207 | else | 199 | else |
| 208 | { | 200 | { |
| 209 | EVP_CipherUpdate(&(ctx->cipher), | 201 | EVP_CipherUpdate(&(ctx->cipher), |
| 210 | (unsigned char *)ctx->buf,&ctx->buf_len, | 202 | (unsigned char *)ctx->buf,&ctx->buf_len, |
| 211 | (unsigned char *)&(ctx->buf[8]),i); | 203 | (unsigned char *)&(ctx->buf[BUF_OFFSET]),i); |
| 212 | ctx->cont=1; | 204 | ctx->cont=1; |
| 205 | /* Note: it is possible for EVP_CipherUpdate to | ||
| 206 | * decrypt zero bytes because this is or looks like | ||
| 207 | * the final block: if this happens we should retry | ||
| 208 | * and either read more data or decrypt the final | ||
| 209 | * block | ||
| 210 | */ | ||
| 211 | if(ctx->buf_len == 0) continue; | ||
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | if (ctx->buf_len <= outl) | 214 | if (ctx->buf_len <= outl) |
| 216 | i=ctx->buf_len; | 215 | i=ctx->buf_len; |
| 217 | else | 216 | else |
| 218 | i=outl; | 217 | i=outl; |
| 219 | |||
| 220 | if (i <= 0) break; | 218 | if (i <= 0) break; |
| 221 | memcpy(out,ctx->buf,i); | 219 | memcpy(out,ctx->buf,i); |
| 222 | ret+=i; | 220 | ret+=i; |
| @@ -230,10 +228,7 @@ int outl; | |||
| 230 | return((ret == 0)?ctx->cont:ret); | 228 | return((ret == 0)?ctx->cont:ret); |
| 231 | } | 229 | } |
| 232 | 230 | ||
| 233 | static int enc_write(b,in,inl) | 231 | static int enc_write(BIO *b, const char *in, int inl) |
| 234 | BIO *b; | ||
| 235 | char *in; | ||
| 236 | int inl; | ||
| 237 | { | 232 | { |
| 238 | int ret=0,n,i; | 233 | int ret=0,n,i; |
| 239 | BIO_ENC_CTX *ctx; | 234 | BIO_ENC_CTX *ctx; |
| @@ -288,16 +283,13 @@ int inl; | |||
| 288 | return(ret); | 283 | return(ret); |
| 289 | } | 284 | } |
| 290 | 285 | ||
| 291 | static long enc_ctrl(b,cmd,num,ptr) | 286 | static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) |
| 292 | BIO *b; | ||
| 293 | int cmd; | ||
| 294 | long num; | ||
| 295 | char *ptr; | ||
| 296 | { | 287 | { |
| 297 | BIO *dbio; | 288 | BIO *dbio; |
| 298 | BIO_ENC_CTX *ctx,*dctx; | 289 | BIO_ENC_CTX *ctx,*dctx; |
| 299 | long ret=1; | 290 | long ret=1; |
| 300 | int i; | 291 | int i; |
| 292 | EVP_CIPHER_CTX **c_ctx; | ||
| 301 | 293 | ||
| 302 | ctx=(BIO_ENC_CTX *)b->ptr; | 294 | ctx=(BIO_ENC_CTX *)b->ptr; |
| 303 | 295 | ||
| @@ -306,7 +298,7 @@ char *ptr; | |||
| 306 | case BIO_CTRL_RESET: | 298 | case BIO_CTRL_RESET: |
| 307 | ctx->ok=1; | 299 | ctx->ok=1; |
| 308 | ctx->finished=0; | 300 | ctx->finished=0; |
| 309 | EVP_CipherInit(&(ctx->cipher),NULL,NULL,NULL, | 301 | EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL, |
| 310 | ctx->cipher.encrypt); | 302 | ctx->cipher.encrypt); |
| 311 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | 303 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); |
| 312 | break; | 304 | break; |
| @@ -343,7 +335,7 @@ again: | |||
| 343 | { | 335 | { |
| 344 | ctx->finished=1; | 336 | ctx->finished=1; |
| 345 | ctx->buf_off=0; | 337 | ctx->buf_off=0; |
| 346 | ret=EVP_CipherFinal(&(ctx->cipher), | 338 | ret=EVP_CipherFinal_ex(&(ctx->cipher), |
| 347 | (unsigned char *)ctx->buf, | 339 | (unsigned char *)ctx->buf, |
| 348 | &(ctx->buf_len)); | 340 | &(ctx->buf_len)); |
| 349 | ctx->ok=(int)ret; | 341 | ctx->ok=(int)ret; |
| @@ -364,7 +356,11 @@ again: | |||
| 364 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | 356 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); |
| 365 | BIO_copy_next_retry(b); | 357 | BIO_copy_next_retry(b); |
| 366 | break; | 358 | break; |
| 367 | 359 | case BIO_C_GET_CIPHER_CTX: | |
| 360 | c_ctx=(EVP_CIPHER_CTX **)ptr; | ||
| 361 | (*c_ctx)= &(ctx->cipher); | ||
| 362 | b->init=1; | ||
| 363 | break; | ||
| 368 | case BIO_CTRL_DUP: | 364 | case BIO_CTRL_DUP: |
| 369 | dbio=(BIO *)ptr; | 365 | dbio=(BIO *)ptr; |
| 370 | dctx=(BIO_ENC_CTX *)dbio->ptr; | 366 | dctx=(BIO_ENC_CTX *)dbio->ptr; |
| @@ -378,6 +374,20 @@ again: | |||
| 378 | return(ret); | 374 | return(ret); |
| 379 | } | 375 | } |
| 380 | 376 | ||
| 377 | static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) | ||
| 378 | { | ||
| 379 | long ret=1; | ||
| 380 | |||
| 381 | if (b->next_bio == NULL) return(0); | ||
| 382 | switch (cmd) | ||
| 383 | { | ||
| 384 | default: | ||
| 385 | ret=BIO_callback_ctrl(b->next_bio,cmd,fp); | ||
| 386 | break; | ||
| 387 | } | ||
| 388 | return(ret); | ||
| 389 | } | ||
| 390 | |||
| 381 | /* | 391 | /* |
| 382 | void BIO_set_cipher_ctx(b,c) | 392 | void BIO_set_cipher_ctx(b,c) |
| 383 | BIO *b; | 393 | BIO *b; |
| @@ -398,26 +408,22 @@ EVP_CIPHER_ctx *c; | |||
| 398 | } | 408 | } |
| 399 | */ | 409 | */ |
| 400 | 410 | ||
| 401 | void BIO_set_cipher(b,c,k,i,e) | 411 | void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, unsigned char *k, |
| 402 | BIO *b; | 412 | unsigned char *i, int e) |
| 403 | EVP_CIPHER *c; | ||
| 404 | unsigned char *k; | ||
| 405 | unsigned char *i; | ||
| 406 | int e; | ||
| 407 | { | 413 | { |
| 408 | BIO_ENC_CTX *ctx; | 414 | BIO_ENC_CTX *ctx; |
| 409 | 415 | ||
| 410 | if (b == NULL) return; | 416 | if (b == NULL) return; |
| 411 | 417 | ||
| 412 | if ((b->callback != NULL) && | 418 | if ((b->callback != NULL) && |
| 413 | (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0)) | 419 | (b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,0L) <= 0)) |
| 414 | return; | 420 | return; |
| 415 | 421 | ||
| 416 | b->init=1; | 422 | b->init=1; |
| 417 | ctx=(BIO_ENC_CTX *)b->ptr; | 423 | ctx=(BIO_ENC_CTX *)b->ptr; |
| 418 | EVP_CipherInit(&(ctx->cipher),c,k,i,e); | 424 | EVP_CipherInit_ex(&(ctx->cipher),c,NULL, k,i,e); |
| 419 | 425 | ||
| 420 | if (b->callback != NULL) | 426 | if (b->callback != NULL) |
| 421 | b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L); | 427 | b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,1L); |
| 422 | } | 428 | } |
| 423 | 429 | ||
