1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (c) 2014, Google Inc.
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Permission to use, copy, modify, and/or distribute this software for any
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * purpose with or without fee is hereby granted, provided that the above
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copyright notice and this permission notice appear in all copies.
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <assert.h>
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <limits.h>
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h>
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/aead.h>
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/cipher.h>
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h>
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/hmac.h>
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/md5.h>
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h>
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/sha.h>
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h"
2869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include "../internal.h"
298ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan#include "../fipsmodule/cipher/internal.h"
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langleytypedef struct {
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_CIPHER_CTX cipher_ctx;
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_MD_CTX md_ctx;
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} AEAD_SSL3_CTX;
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int ssl3_mac(AEAD_SSL3_CTX *ssl3_ctx, uint8_t *out, unsigned *out_len,
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                    const uint8_t *ad, size_t ad_len, const uint8_t *in,
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                    size_t in_len) {
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t md_size = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t pad_len = (md_size == 20) ? 40 : 48;
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* To allow for CBC mode which changes cipher length, |ad| doesn't include the
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * length for legacy ciphers. */
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t ad_extra[2];
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ad_extra[0] = (uint8_t)(in_len >> 8);
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ad_extra[1] = (uint8_t)(in_len & 0xff);
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_MD_CTX md_ctx;
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_MD_CTX_init(&md_ctx);
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t pad[48];
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t tmp[EVP_MAX_MD_SIZE];
5469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  OPENSSL_memset(pad, 0x36, pad_len);
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) ||
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&md_ctx, pad, pad_len) ||
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&md_ctx, ad, ad_len) ||
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&md_ctx, ad_extra, sizeof(ad_extra)) ||
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&md_ctx, in, in_len) ||
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestFinal_ex(&md_ctx, tmp, NULL)) {
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    EVP_MD_CTX_cleanup(&md_ctx);
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
6569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  OPENSSL_memset(pad, 0x5c, pad_len);
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) ||
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&md_ctx, pad, pad_len) ||
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&md_ctx, tmp, md_size) ||
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestFinal_ex(&md_ctx, out, out_len)) {
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    EVP_MD_CTX_cleanup(&md_ctx);
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_MD_CTX_cleanup(&md_ctx);
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void aead_ssl3_cleanup(EVP_AEAD_CTX *ctx) {
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_CIPHER_CTX_cleanup(&ssl3_ctx->cipher_ctx);
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_MD_CTX_cleanup(&ssl3_ctx->md_ctx);
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  OPENSSL_free(ssl3_ctx);
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->aead_state = NULL;
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
86e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                          size_t tag_len, enum evp_aead_direction_t dir,
87e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                          const EVP_CIPHER *cipher, const EVP_MD *md) {
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      tag_len != EVP_MD_size(md)) {
90b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (key_len != EVP_AEAD_key_length(ctx->aead)) {
95b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t mac_key_len = EVP_MD_size(md);
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t enc_key_len = EVP_CIPHER_key_length(cipher);
101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  assert(mac_key_len + enc_key_len + EVP_CIPHER_iv_length(cipher) == key_len);
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX));
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ssl3_ctx == NULL) {
105b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx);
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_MD_CTX_init(&ssl3_ctx->md_ctx);
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->aead_state = ssl3_ctx;
112e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len],
113e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                         &key[mac_key_len + enc_key_len],
114e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                         dir == evp_aead_seal) ||
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestInit_ex(&ssl3_ctx->md_ctx, md, NULL) ||
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !EVP_DigestUpdate(&ssl3_ctx->md_ctx, key, mac_key_len)) {
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_cleanup(ctx);
118e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    ctx->aead_state = NULL;
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  EVP_CIPHER_CTX_set_padding(&ssl3_ctx->cipher_ctx, 0);
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1268ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloanstatic int aead_ssl3_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out,
1278ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan                                  uint8_t *out_tag, size_t *out_tag_len,
1288ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan                                  size_t max_out_tag_len, const uint8_t *nonce,
1298ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan                                  size_t nonce_len, const uint8_t *in,
130927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan                                  size_t in_len, const uint8_t *extra_in,
131927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan                                  size_t extra_in_len, const uint8_t *ad,
1328ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan                                  size_t ad_len) {
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
135e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!ssl3_ctx->cipher_ctx.encrypt) {
136e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    /* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
137b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
138e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
139e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
140e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
1418ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  if (in_len > INT_MAX) {
142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* EVP_CIPHER takes int as input. */
143b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1478ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  const size_t max_overhead = EVP_AEAD_max_overhead(ctx->aead);
1488ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  if (max_out_tag_len < max_overhead) {
149b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (nonce_len != 0) {
154b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ad_len != 11 - 2 /* length bytes */) {
159b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Compute the MAC. This must be first in case the operation is being done
164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * in-place. */
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t mac[EVP_MAX_MD_SIZE];
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  unsigned mac_len;
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ssl3_mac(ssl3_ctx, mac, &mac_len, ad, ad_len, in, in_len)) {
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Encrypt the input. */
172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int len;
173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in,
174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         (int)in_len)) {
175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1788ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  const size_t block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx);
1798ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan
1808ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  /* Feed the MAC into the cipher in two steps. First complete the final partial
1818ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan   * block from encrypting the input and split the result between |out| and
1828ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan   * |out_tag|. Then encrypt the remainder. */
1838ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan
1848ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  size_t early_mac_len = (block_size - (in_len % block_size)) % block_size;
1858ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  if (early_mac_len != 0) {
1868ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    assert(len + block_size - early_mac_len == in_len);
1878ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    uint8_t buf[EVP_MAX_BLOCK_LENGTH];
1888ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    int buf_len;
1898ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, buf, &buf_len, mac,
1908ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan                           (int)early_mac_len)) {
1918ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan      return 0;
1928ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    }
1938ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    assert(buf_len == (int)block_size);
1948ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    OPENSSL_memcpy(out + len, buf, block_size - early_mac_len);
1958ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    OPENSSL_memcpy(out_tag, buf + block_size - early_mac_len, early_mac_len);
1968ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  }
1978ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  size_t tag_len = early_mac_len;
1988ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan
1998ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len,
2008ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan                         mac + tag_len, mac_len - tag_len)) {
201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2038ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  tag_len += len;
204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (block_size > 1) {
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    assert(block_size <= 256);
207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    assert(EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Compute padding and feed that into the cipher. */
210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    uint8_t padding[256];
2118ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    size_t padding_len = block_size - ((in_len + mac_len) % block_size);
21269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    OPENSSL_memset(padding, 0, padding_len - 1);
213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    padding[padding_len - 1] = padding_len - 1;
2148ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len, padding,
215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                           (int)padding_len)) {
216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2188ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    tag_len += len;
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2218ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  if (!EVP_EncryptFinal_ex(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len)) {
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2248ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  tag_len += len;
2258ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  assert(tag_len <= max_overhead);
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2278ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan  *out_tag_len = tag_len;
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         size_t *out_len, size_t max_out_len,
233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         const uint8_t *nonce, size_t nonce_len,
234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         const uint8_t *in, size_t in_len,
235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         const uint8_t *ad, size_t ad_len) {
236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
238e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ssl3_ctx->cipher_ctx.encrypt) {
239e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    /* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
240b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
241e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
242e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
243e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (in_len < mac_len) {
246b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (max_out_len < in_len) {
251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* This requires that the caller provide space for the MAC, even though it
252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * will always be removed on return. */
253b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (nonce_len != 0) {
258b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ad_len != 11 - 2 /* length bytes */) {
263b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
265d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (in_len > INT_MAX) {
268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* EVP_CIPHER takes int as input. */
269b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Decrypt to get the plaintext + MAC + padding. */
274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t total = 0;
275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int len;
276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EVP_DecryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in, (int)in_len)) {
277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  total += len;
280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EVP_DecryptFinal_ex(&ssl3_ctx->cipher_ctx, out + total, &len)) {
281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  total += len;
284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  assert(total == in_len);
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
286c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin  /* Remove CBC padding and MAC. This would normally be timing-sensitive, but
287c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin   * SSLv3 CBC ciphers are already broken. Support will be removed eventually.
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * https://www.openssl.org/~bodo/ssl-poodle.pdf */
289c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin  size_t data_len;
290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    unsigned padding_length = out[total - 1];
292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (total < padding_length + 1 + mac_len) {
293b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
296d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* The padding must be minimal. */
297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) {
298b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    data_len = total - padding_length - 1 - mac_len;
302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    data_len = total - mac_len;
304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Compute the MAC and compare against the one in the record. */
307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t mac[EVP_MAX_MD_SIZE];
308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ssl3_mac(ssl3_ctx, mac, NULL, ad, ad_len, out, data_len)) {
309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) {
312b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out_len = data_len;
317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
320fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleystatic int aead_ssl3_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
321fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley                            size_t *out_iv_len) {
322fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
323fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  const size_t iv_len = EVP_CIPHER_CTX_iv_length(&ssl3_ctx->cipher_ctx);
324fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  if (iv_len <= 1) {
325fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley    return 0;
326fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  }
327fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley
328fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  *out_iv = ssl3_ctx->cipher_ctx.iv;
329fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  *out_iv_len = iv_len;
330fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  return 1;
331fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley}
332fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley
333d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int aead_aes_128_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
334e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                           size_t key_len, size_t tag_len,
335e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                           enum evp_aead_direction_t dir) {
336e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(),
337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        EVP_sha1());
338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
340d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int aead_aes_256_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
341e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                           size_t key_len, size_t tag_len,
342e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                           enum evp_aead_direction_t dir) {
343e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(),
344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        EVP_sha1());
345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
346d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx,
347e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                            const uint8_t *key, size_t key_len,
348e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                            size_t tag_len,
349e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                            enum evp_aead_direction_t dir) {
350e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(),
351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        EVP_sha1());
352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
354b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic int aead_null_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
355b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                    size_t key_len, size_t tag_len,
356b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                    enum evp_aead_direction_t dir) {
357b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
358b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                        EVP_sha1());
359b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
360b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
361d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = {
362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SHA_DIGEST_LENGTH + 16 + 16, /* key len (SHA1 + AES128 + IV) */
363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0,                           /* nonce len */
364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    16 + SHA_DIGEST_LENGTH,      /* overhead (padding + SHA1) */
365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SHA_DIGEST_LENGTH,           /* max tag length */
366927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    0,                           /* seal_scatter_supports_extra_in */
367927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan
368e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    NULL, /* init */
369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_aes_128_cbc_sha1_ssl3_init,
370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_cleanup,
371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_open,
3728ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    aead_ssl3_seal_scatter,
3738ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    NULL, /* open_gather */
374fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley    aead_ssl3_get_iv,
375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
377d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SHA_DIGEST_LENGTH + 32 + 16, /* key len (SHA1 + AES256 + IV) */
379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0,                           /* nonce len */
380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    16 + SHA_DIGEST_LENGTH,      /* overhead (padding + SHA1) */
381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SHA_DIGEST_LENGTH,           /* max tag length */
382927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    0,                           /* seal_scatter_supports_extra_in */
383927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan
384e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    NULL, /* init */
385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_aes_256_cbc_sha1_ssl3_init,
386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_cleanup,
387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_open,
3888ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    aead_ssl3_seal_scatter,
3898ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    NULL, /* open_gather */
390fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley    aead_ssl3_get_iv,
391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
393d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SHA_DIGEST_LENGTH + 24 + 8, /* key len (SHA1 + 3DES + IV) */
395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0,                          /* nonce len */
396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    8 + SHA_DIGEST_LENGTH,      /* overhead (padding + SHA1) */
397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SHA_DIGEST_LENGTH,          /* max tag length */
398927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    0,                          /* seal_scatter_supports_extra_in */
399927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan
400e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    NULL, /* init */
401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_des_ede3_cbc_sha1_ssl3_init,
402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_cleanup,
403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    aead_ssl3_open,
4048ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    aead_ssl3_seal_scatter,
4058ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    NULL, /* open_gather */
406fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley    aead_ssl3_get_iv,
407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
409b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic const EVP_AEAD aead_null_sha1_ssl3 = {
410927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    SHA_DIGEST_LENGTH, /* key len */
411927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    0,                 /* nonce len */
412927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    SHA_DIGEST_LENGTH, /* overhead (SHA1) */
413927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    SHA_DIGEST_LENGTH, /* max tag length */
414927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    0,                 /* seal_scatter_supports_extra_in */
415927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan
416927a49544eb76fe28bcca2552db0168fd2efc502Robert Sloan    NULL, /* init */
417b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    aead_null_sha1_ssl3_init,
418b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    aead_ssl3_cleanup,
419b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    aead_ssl3_open,
4208ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    aead_ssl3_seal_scatter,
4218ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    NULL, /* open_gather */
4228ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan    NULL, /* get_iv */
423b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root};
424b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
425d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void) {
426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return &aead_aes_128_cbc_sha1_ssl3;
427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
429d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void) {
430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return &aead_aes_256_cbc_sha1_ssl3;
431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
433d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) {
434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return &aead_des_ede3_cbc_sha1_ssl3;
435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
436b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
437b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootconst EVP_AEAD *EVP_aead_null_sha1_ssl3(void) { return &aead_null_sha1_ssl3; }
438