hcrypto: Fix EVP_CipherUpdate() bugs
This commit is contained in:
		 Nicolas Williams
					Nicolas Williams
				
			
				
					committed by
					
						 Jeffrey Altman
						Jeffrey Altman
					
				
			
			
				
	
			
			
			 Jeffrey Altman
						Jeffrey Altman
					
				
			
						parent
						
							47e6c68de8
						
					
				
				
					commit
					11846fcabb
				
			| @@ -857,37 +857,34 @@ EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, void *out, int *outlen, | |||||||
|  |  | ||||||
|     *outlen = 0; |     *outlen = 0; | ||||||
|  |  | ||||||
|     /** |     /* | ||||||
|      * If there in no spare bytes in the left from last Update and the |      * If there in no bytes left over from the last Update and the | ||||||
|      * input length is on the block boundery, the EVP_CipherUpdate() |      * input length is on a block boundary, then we can take a | ||||||
|      * function can take a shortcut (and preformance gain) and |      * shortcut (and preformance gain) and directly encrypt the | ||||||
|      * directly encrypt the data, otherwise we hav to fix it up and |      * data. | ||||||
|      * store extra it the EVP_CIPHER_CTX. |  | ||||||
|      */ |      */ | ||||||
|     if (ctx->buf_len == 0 && (inlen & ctx->block_mask) == 0) { |     if (ctx->buf_len == 0 && inlen && (inlen & ctx->block_mask) == 0) { | ||||||
| 	ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen); | 	ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen); | ||||||
| 	if (ret == 1) | 	if (ret == 1) | ||||||
| 	    *outlen = inlen; | 	    *outlen = inlen; | ||||||
| 	else |         else | ||||||
| 	    *outlen = 0; | 	    *outlen = 0; | ||||||
| 	return ret; | 	return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     blocksize = EVP_CIPHER_CTX_block_size(ctx); |     blocksize = EVP_CIPHER_CTX_block_size(ctx); | ||||||
|     left = blocksize - ctx->buf_len; |     left = blocksize - ctx->buf_len; | ||||||
|     assert(left > 0); |     assert(left > 0); | ||||||
|  |  | ||||||
|     if (ctx->buf_len) { |     if (ctx->buf_len) { | ||||||
|  | 	/* If we can't fill one block in the buffer, save the input there */ | ||||||
| 	/* if total buffer is smaller then input, store locally */ |  | ||||||
| 	if (inlen < left) { | 	if (inlen < left) { | ||||||
| 	    memcpy(ctx->buf + ctx->buf_len, in, inlen); | 	    memcpy(ctx->buf + ctx->buf_len, in, inlen); | ||||||
| 	    ctx->buf_len += inlen; | 	    ctx->buf_len += inlen; | ||||||
| 	    return 1; | 	    return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* fill in local buffer and encrypt */ | 	/* Fill the buffer and encrypt */ | ||||||
| 	memcpy(ctx->buf + ctx->buf_len, in, left); | 	memcpy(ctx->buf + ctx->buf_len, in, left); | ||||||
| 	ret = (*ctx->cipher->do_cipher)(ctx, out, ctx->buf, blocksize); | 	ret = (*ctx->cipher->do_cipher)(ctx, out, ctx->buf, blocksize); | ||||||
| 	memset_s(ctx->buf, blocksize, 0, blocksize); | 	memset_s(ctx->buf, blocksize, 0, blocksize); | ||||||
| @@ -905,12 +902,16 @@ EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, void *out, int *outlen, | |||||||
| 	ctx->buf_len = (inlen & ctx->block_mask); | 	ctx->buf_len = (inlen & ctx->block_mask); | ||||||
| 	inlen &= ~ctx->block_mask; | 	inlen &= ~ctx->block_mask; | ||||||
|  |  | ||||||
| 	ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen); |         if (inlen) { | ||||||
| 	if (ret != 1) |             /* Encrypt all the whole blocks of input that we have */ | ||||||
| 	    return ret; |             ret = (*ctx->cipher->do_cipher)(ctx, out, in, inlen); | ||||||
|  |             if (ret != 1) | ||||||
|  |                 return ret; | ||||||
|  |         } | ||||||
|  |  | ||||||
| 	*outlen += inlen; | 	*outlen += inlen; | ||||||
|  |  | ||||||
|  |         /* Save the tail of the input, if any */ | ||||||
| 	in = ((unsigned char *)in) + inlen; | 	in = ((unsigned char *)in) + inlen; | ||||||
| 	memcpy(ctx->buf, in, ctx->buf_len); | 	memcpy(ctx->buf, in, ctx->buf_len); | ||||||
|     } |     } | ||||||
| @@ -969,7 +970,7 @@ EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, void *out, int *outlen) | |||||||
|  * @param in in data to the operation. |  * @param in in data to the operation. | ||||||
|  * @param size length of data. |  * @param size length of data. | ||||||
|  * |  * | ||||||
|  * @return 1 on success. |  * @return bytes encrypted on success, zero on failure. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| int | int | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user