195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */ 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/cipher.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <string.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <assert.h> 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h> 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/obj.h> 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "internal.h" 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst EVP_CIPHER *EVP_get_cipherbynid(int nid) { 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch (nid) { 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case NID_des_ede3_cbc: 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_des_ede3_cbc(); 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case NID_des_ede_cbc: 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_des_cbc(); 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case NID_aes_128_cbc: 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_aes_128_cbc(); 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case NID_aes_256_cbc: 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_aes_256_cbc(); 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyEVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) { 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx) { 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_CIPHER_CTX_init(ctx); 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx; 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *key, const unsigned char *iv, int enc) { 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cipher) { 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_CIPHER_CTX_init(ctx); 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (c->cipher != NULL && c->cipher->cleanup && !c->cipher->cleanup(c)) { 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (c->cipher_data) { 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(c->cipher_data); 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(c, 0, sizeof(EVP_CIPHER_CTX)); 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) { 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx) { 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_CIPHER_CTX_cleanup(ctx); 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(ctx); 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in == NULL || in->cipher == NULL) { 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, CIPHER_R_INPUT_NOT_INITIALIZED); 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_CIPHER_CTX_cleanup(out); 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(out, in, sizeof(EVP_CIPHER_CTX)); 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in->cipher_data && in->cipher->ctx_size) { 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!out->cipher_data) { 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, ERR_R_MALLOC_FAILURE); 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1437578f3f0dea091a3392f0be3216989bdc7355ad2Adam Langley if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) { 1447578f3f0dea091a3392f0be3216989bdc7355ad2Adam Langley return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); 1457578f3f0dea091a3392f0be3216989bdc7355ad2Adam Langley } 1467578f3f0dea091a3392f0be3216989bdc7355ad2Adam Langley 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ENGINE *engine, const uint8_t *key, const uint8_t *iv, 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int enc) { 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (enc == -1) { 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley enc = ctx->encrypt; 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (enc) { 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley enc = 1; 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->encrypt = enc; 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cipher) { 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Ensure a context left from last time is cleared (the previous check 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * attempted to avoid this if the same ENGINE and EVP_CIPHER could be 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * used). */ 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher) { 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley EVP_CIPHER_CTX_cleanup(ctx); 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Restore encrypt and flags */ 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->encrypt = enc; 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->cipher = cipher; 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->ctx_size) { 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->cipher_data) { 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, ERR_R_MALLOC_FAILURE); 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->cipher_data = NULL; 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->key_len = cipher->key_len; 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->flags = 0; 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_INITIALIZATION_ERROR); 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else if (!ctx->cipher) { 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_NO_CIPHER_SET); 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* we assume block size is a power of 2 in *cryptUpdate */ 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->cipher->block_size == 16); 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch (EVP_CIPHER_CTX_mode(ctx)) { 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_CIPH_STREAM_CIPHER: 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_CIPH_ECB_MODE: 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_CIPH_CFB_MODE: 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_CIPH_OFB_MODE: 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* fall-through */ 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_CIPH_CBC_MODE: 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv)); 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (iv) { 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case EVP_CIPH_CTR_MODE: 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Don't reuse IV for CTR mode */ 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (iv) { 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->cipher->init(ctx, key, iv, enc)) { 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->buf_len = 0; 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->final_used = 0; 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->block_mask = ctx->cipher->block_size - 1; 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ENGINE *impl, const uint8_t *key, const uint8_t *iv) { 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ENGINE *impl, const uint8_t *key, const uint8_t *iv) { 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *in, int in_len) { 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i, j, bl; 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ctx->cipher->cipher(ctx, out, in, in_len); 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i < 0) { 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = i; 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_len <= 0) { 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return in_len == 0; 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->buf_len == 0 && (in_len & ctx->block_mask) == 0) { 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->cipher(ctx, out, in, in_len)) { 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = in_len; 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ctx->buf_len; 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bl = ctx->cipher->block_size; 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(bl <= (int)sizeof(ctx->buf)); 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i != 0) { 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i + in_len < bl) { 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(&ctx->buf[i], in, in_len); 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->buf_len += in_len; 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley j = bl - i; 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(&ctx->buf[i], in, j); 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->cipher->cipher(ctx, out, ctx->buf, bl)) { 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in_len -= j; 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in += j; 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += bl; 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = bl; 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = in_len & ctx->block_mask; 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in_len -= i; 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_len > 0) { 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->cipher->cipher(ctx, out, in, in_len)) { 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len += in_len; 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i != 0) { 31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(ctx->buf, &in[in_len], i); 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->buf_len = i; 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int n, ret; 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned int i, b, bl; 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ctx->cipher->cipher(ctx, out, NULL, 0); 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret < 0) { 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = ret; 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley b = ctx->cipher->block_size; 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(b <= sizeof(ctx->buf)); 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (b == 1) { 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bl = ctx->buf_len; 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->flags & EVP_CIPH_NO_PADDING) { 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (bl) { 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_EncryptFinal_ex, 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n = b - bl; 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = bl; i < b; i++) { 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->buf[i] = n; 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ctx->cipher->cipher(ctx, out, ctx->buf, b); 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret) { 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = b; 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *in, int in_len) { 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int fix_len; 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned int b; 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int r = ctx->cipher->cipher(ctx, out, in, in_len); 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (r < 0) { 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = r; 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_len <= 0) { 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return in_len == 0; 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->flags & EVP_CIPH_NO_PADDING) { 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley b = ctx->cipher->block_size; 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(b <= sizeof(ctx->final)); 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->final_used) { 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(out, ctx->final, b); 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += b; 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley fix_len = 1; 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley fix_len = 0; 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!EVP_EncryptUpdate(ctx, out, out_len, in, in_len)) { 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* if we have 'decrypted' a multiple of block size, make sure 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * we have a copy of this last block */ 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (b > 1 && !ctx->buf_len) { 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len -= b; 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->final_used = 1; 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(ctx->final, &out[*out_len], b); 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->final_used = 0; 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (fix_len) { 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len += b; 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i, n; 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned int b; 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ctx->cipher->cipher(ctx, out, NULL, 0); 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i < 0) { 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = i; 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley b = ctx->cipher->block_size; 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->flags & EVP_CIPH_NO_PADDING) { 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->buf_len) { 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (b > 1) { 45395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->buf_len || !ctx->final_used) { 45495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CIPHER_R_WRONG_FINAL_BLOCK_LENGTH); 45695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 45795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 45895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(b <= sizeof(ctx->final)); 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* The following assumes that the ciphertext has been authenticated. 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Otherwise it provides a padding oracle. */ 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n = ctx->final[b - 1]; 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (n == 0 || n > (int)b) { 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT); 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < n; i++) { 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->final[--b] != n) { 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT); 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n = ctx->cipher->block_size - n; 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < n; i++) { 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out[i] = ctx->final[i]; 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = n; 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, 48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t in_len) { 48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher->cipher(ctx, out, in, in_len); 49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, 49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *in, int in_len) { 49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->encrypt) { 49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); 49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_DecryptUpdate(ctx, out, out_len, in, in_len); 49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { 50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->encrypt) { 50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_EncryptFinal_ex(ctx, out, out_len); 50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return EVP_DecryptFinal_ex(ctx, out, out_len); 50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { 51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher; 51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) { 51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher->nid; 51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) { 51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher->block_size; 51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) { 52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->key_len; 52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) { 52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher->iv_len; 52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) { 53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->app_data; 53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) { 53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->app_data = data; 53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyuint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) { 53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher->flags & ~EVP_CIPH_MODE_MASK; 53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyuint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx) { 54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ctx->cipher->flags & EVP_CIPH_MODE_MASK; 54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) { 54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ret; 54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->cipher) { 54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_NO_CIPHER_SET); 54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!ctx->cipher->ctrl) { 55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_CTRL_NOT_IMPLEMENTED); 55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ctx->cipher->ctrl(ctx, command, arg, ptr); 55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ret == -1) { 55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, 56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED); 56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) { 56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (pad) { 56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->flags &= ~EVP_CIPH_NO_PADDING; 57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->flags |= EVP_CIPH_NO_PADDING; 57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 576539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langleyint EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, unsigned key_len) { 577539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley if (c->key_len == key_len) { 578539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley return 1; 579539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley } 580539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley 581539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { 582539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_set_key_length, 583539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley CIPHER_R_INVALID_KEY_LENGTH); 584539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley return 0; 585539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley } 586539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley 587539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley c->key_len = key_len; 588539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley return 1; 589539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley} 590539112fd4447ba9a2c6f669edd16129d824b8b34Adam Langley 59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_CIPHER_nid(const EVP_CIPHER *cipher) { return cipher->nid; } 59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char *EVP_CIPHER_name(const EVP_CIPHER *cipher) { 59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return OBJ_nid2sn(cipher->nid); 59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { 59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return cipher->block_size; 59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { 60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return cipher->key_len; 60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyunsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { 60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return cipher->iv_len; 60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyuint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher) { 61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return cipher->flags & ~EVP_CIPH_MODE_MASK; 61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyuint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher) { 61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return cipher->flags & EVP_CIPH_MODE_MASK; 61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 616