1219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * All rights reserved. 3219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 4219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * This package is an SSL implementation written 5219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * by Eric Young (eay@cryptsoft.com). 6219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * The implementation was written so as to conform with Netscapes SSL. 7219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 8219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * This library is free for commercial and non-commercial use as long as 9219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * the following conditions are aheared to. The following conditions 10219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA, 11219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * included with this distribution is covered by the same copyright terms 13219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 15219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in 16219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * the code are not to be removed. 17219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * If this package is used in a product, Eric Young should be given attribution 18219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * as the author of the parts of the library used. 19219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * This can be in the form of a textual message at program startup or 20219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * in documentation (online or textual) provided with the package. 21219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 22219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * Redistribution and use in source and binary forms, with or without 23219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * modification, are permitted provided that the following conditions 24219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * are met: 25219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 1. Redistributions of source code must retain the copyright 26219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * notice, this list of conditions and the following disclaimer. 27219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 28219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * notice, this list of conditions and the following disclaimer in the 29219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * documentation and/or other materials provided with the distribution. 30219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 3. All advertising materials mentioning features or use of this software 31219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * must display the following acknowledgement: 32219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * "This product includes cryptographic software written by 33219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * Eric Young (eay@cryptsoft.com)" 34219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * The word 'cryptographic' can be left out if the rouines from the library 35219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * being used are not cryptographic related :-). 36219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from 37219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * the apps directory (application code) you must include an acknowledgement: 38219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 40219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * SUCH DAMAGE. 51219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 52219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * The licence and distribution terms for any publically available version or 53219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * derivative of this code cannot be changed. i.e. this code cannot simply be 54219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * copied and put under another distribution licence 55219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * [including the GNU Public Licence.] 56219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org */ 57219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 58219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org#include <limits.h> 59219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org#include <string.h> 60219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 61219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org#include <openssl/evp.h> 62219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org#include <openssl/err.h> 63219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 64219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org#include "evp_locl.h" 65219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 66219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgsize_t EVP_AEAD_key_length(const EVP_AEAD *aead) 67219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 68219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return aead->key_len; 69219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 70219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 71219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgsize_t EVP_AEAD_nonce_length(const EVP_AEAD *aead) 72219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 73219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return aead->nonce_len; 74219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 75219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 76219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgsize_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) 77219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 78219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return aead->overhead; 79219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 80219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 81219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgsize_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) 82219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 83219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return aead->max_tag_len; 84219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 85219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 86219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgint EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, 87219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *key, size_t key_len, 88219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org size_t tag_len, ENGINE *impl) 89219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 90219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org ctx->aead = aead; 91219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (key_len != aead->key_len) 92219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 93219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org EVPerr(EVP_F_EVP_AEAD_CTX_INIT,EVP_R_UNSUPPORTED_KEY_SIZE); 94219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return 0; 95219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 96219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return aead->init(ctx, key, key_len, tag_len); 97219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 98219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 99219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgvoid EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) 100219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 101219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (ctx->aead == NULL) 102219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return; 103219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org ctx->aead->cleanup(ctx); 104219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org ctx->aead = NULL; 105219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 106219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 107219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org/* check_alias returns 0 if |out| points within the buffer determined by |in| 108219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * and |in_len| and 1 otherwise. 109219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 110219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * When processing, there's only an issue if |out| points within in[:in_len] 111219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * and isn't equal to |in|. If that's the case then writing the output will 112219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * stomp input that hasn't been read yet. 113219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * 114219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * This function checks for that case. */ 115219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgstatic int check_alias(const unsigned char *in, size_t in_len, 116219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *out) 117219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 118219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (out <= in) 119219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return 1; 120219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (in + in_len <= out) 121219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return 1; 122219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return 0; 123219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 124219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 125219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, 126219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org unsigned char *out, size_t max_out_len, 127219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *nonce, size_t nonce_len, 128219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *in, size_t in_len, 129219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *ad, size_t ad_len) 130219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 131219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org size_t possible_out_len = in_len + ctx->aead->overhead; 132219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org ssize_t r; 133219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 134219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (possible_out_len < in_len /* overflow */ || 135219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org possible_out_len > SSIZE_MAX /* return value cannot be 136219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org represented */) 137219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 138219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE); 139219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org goto error; 140219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 141219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 142219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (!check_alias(in, in_len, out)) 143219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 144219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT); 145219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org goto error; 146219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 147219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 148219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org r = ctx->aead->seal(ctx, out, max_out_len, nonce, nonce_len, 149219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org in, in_len, ad, ad_len); 150219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (r >= 0) 151219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return r; 152219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 153219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgerror: 154219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org /* In the event of an error, clear the output buffer so that a caller 155219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * that doesn't check the return value doesn't send raw data. */ 156219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org memset(out, 0, max_out_len); 157219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return -1; 158219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 159219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 160219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, 161219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org unsigned char *out, size_t max_out_len, 162219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *nonce, size_t nonce_len, 163219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *in, size_t in_len, 164219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org const unsigned char *ad, size_t ad_len) 165219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 166219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org ssize_t r; 167219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 168219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (in_len > SSIZE_MAX) 169219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 170219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_TOO_LARGE); 171219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org goto error; /* may not be able to represent return value. */ 172219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 173219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 174219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (!check_alias(in, in_len, out)) 175219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org { 176219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT); 177219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org goto error; 178219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 179219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 180219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org r = ctx->aead->open(ctx, out, max_out_len, nonce, nonce_len, 181219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org in, in_len, ad, ad_len); 182219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 183219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org if (r >= 0) 184219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return r; 185219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org 186219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgerror: 187219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org /* In the event of an error, clear the output buffer so that a caller 188219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * that doesn't check the return value doesn't try and process bad 189219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * data. */ 190219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org memset(out, 0, max_out_len); 191219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org return -1; 192219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org } 193