Files
boringssl/include/openssl/aead.h
T
Adam Langley bd6f41c308 Running spelling and grammar checks over comments.
... and then run clang-format on the changed files to reflow any comment
blocks that exceeded line lengths. (Which generated a bunch of noise
formatting changes, but probably that reduces noise in future CLs.)

No semantic change to the code.

Change-Id: I455da9faaaedda3e751ac91b5eb43cbc662d68a6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/97367
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Auto-Submit: Adam Langley <agl@google.com>
2026-06-16 06:19:51 -07:00

663 lines
30 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright 2014 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OPENSSL_HEADER_AEAD_H
#define OPENSSL_HEADER_AEAD_H
#include <openssl/base.h> // IWYU pragma: export
#if defined(__cplusplus)
extern "C" {
#endif
// Authenticated Encryption with Additional Data.
//
// AEAD couples confidentiality and integrity in a single primitive. AEAD
// algorithms take a key and then can seal and open individual messages. Each
// message has a unique, per-message nonce and, optionally, additional data
// which is authenticated but not included in the ciphertext.
//
// The `EVP_AEAD_CTX_init` function initialises an `EVP_AEAD_CTX` structure and
// performs any precomputation needed to use `aead` with `key`. The length of
// the key, `key_len`, is given in bytes.
//
// The `tag_len` argument contains the length of the tags, in bytes, and allows
// for the processing of truncated authenticators. A zero value indicates that
// the default tag length should be used and this is defined as
// `EVP_AEAD_DEFAULT_TAG_LENGTH` in order to make the code clear. Using
// truncated tags increases an attacker's chance of creating a valid forgery.
// Be aware that the attacker's chance may increase more than exponentially as
// would naively be expected.
//
// When no longer needed, the initialised `EVP_AEAD_CTX` structure must be
// passed to `EVP_AEAD_CTX_cleanup`, which will deallocate any memory used.
//
// With an `EVP_AEAD_CTX` in hand, one can seal and open messages. These
// operations are intended to meet the standard notions of privacy and
// authenticity for authenticated encryption. For formal definitions see
// Bellare and Namprempre, "Authenticated encryption: relations among notions
// and analysis of the generic composition paradigm," Lecture Notes in Computer
// Science B<1976> (2000), 531545,
// http://www-cse.ucsd.edu/~mihir/papers/oem.html.
//
// When sealing messages, a nonce must be given. The length of the nonce is
// fixed by the AEAD in use and is returned by `EVP_AEAD_nonce_length`. *The
// nonce must be unique for all messages with the same key*. This is critically
// important - nonce reuse may completely undermine the security of the AEAD.
// Nonces may be predictable and public, so long as they are unique. Uniqueness
// may be achieved with a simple counter or, if large enough, may be generated
// randomly. The nonce must be passed into the "open" operation by the receiver
// so must either be implicit (e.g. a counter), or must be transmitted along
// with the sealed message.
//
// The "seal" and "open" operations are atomic - an entire message must be
// encrypted or decrypted in a single call. Large messages may have to be split
// up in order to accommodate this. When doing so, be mindful of the need not to
// repeat nonces and the possibility that an attacker could duplicate, reorder
// or drop message chunks. For example, using a single key for a given (large)
// message and sealing chunks with nonces counting from zero would be secure as
// long as the number of chunks was securely transmitted. (Otherwise an
// attacker could truncate the message by dropping chunks from the end.)
//
// The number of chunks could be transmitted by prefixing it to the plaintext,
// for example. This also assumes that no other message would ever use the same
// key otherwise the rule that nonces must be unique for a given key would be
// violated.
//
// The "seal" and "open" operations also permit additional data to be
// authenticated via the `ad` parameter. This data is not included in the
// ciphertext and must be identical for both the "seal" and "open" call. This
// permits implicit context to be authenticated but may be empty if not needed.
//
// The "seal" and "open" operations may work in-place if the `out` and `in`
// arguments are equal. Otherwise, if `out` and `in` alias, input data may be
// overwritten before it is read. This situation will cause an error.
//
// The "seal" and "open" operations return one on success and zero on error.
// AEAD algorithms.
// EVP_aead_aes_128_gcm is AES-128 in Galois Counter Mode.
//
// Note: AES-GCM should only be used with 12-byte (96-bit) nonces. Although it
// is specified to take a variable-length nonce, nonces with other lengths are
// effectively randomized, which means one must consider collisions. Unless
// implementing an existing protocol which has already specified incorrect
// parameters, only use 12-byte nonces.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
// EVP_aead_aes_192_gcm is AES-192 in Galois Counter Mode.
//
// WARNING: AES-192 is superfluous and shouldn't exist. NIST should never have
// defined it. Use only when interop with another system requires it, never
// de novo.
//
// Note: AES-GCM should only be used with 12-byte (96-bit) nonces. Although it
// is specified to take a variable-length nonce, nonces with other lengths are
// effectively randomized, which means one must consider collisions. Unless
// implementing an existing protocol which has already specified incorrect
// parameters, only use 12-byte nonces.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_192_gcm(void);
// EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode.
//
// Note: AES-GCM should only be used with 12-byte (96-bit) nonces. Although it
// is specified to take a variable-length nonce, nonces with other lengths are
// effectively randomized, which means one must consider collisions. Unless
// implementing an existing protocol which has already specified incorrect
// parameters, only use 12-byte nonces.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
// EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and
// Poly1305 as described in RFC 8439.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
// EVP_aead_xchacha20_poly1305 is ChaCha20-Poly1305 with an extended nonce that
// makes random generation of nonces safe.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_xchacha20_poly1305(void);
// EVP_aead_aes_128_ctr_hmac_sha256 is AES-128 in CTR mode with HMAC-SHA256 for
// authentication. The nonce is 12 bytes; the bottom 32-bits are used as the
// block counter, thus the maximum plaintext size is 64GB.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void);
// EVP_aead_aes_256_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for
// authentication. See `EVP_aead_aes_128_ctr_hmac_sha256` for details.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void);
// EVP_aead_aes_128_gcm_siv is AES-128 in GCM-SIV mode. See RFC 8452.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void);
// EVP_aead_aes_256_gcm_siv is AES-256 in GCM-SIV mode. See RFC 8452.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void);
// EVP_aead_aes_128_gcm_randnonce is AES-128 in Galois Counter Mode with
// internal nonce generation. The 12-byte nonce is appended to the tag
// and is generated internally. The "tag", for the purpurses of the API, is thus
// 12 bytes larger. The nonce parameter when using this AEAD must be
// zero-length. Since the nonce is random, a single key should not be used for
// more than 2^32 seal operations.
//
// Warning: this is for use for FIPS compliance only. It is probably not
// suitable for other uses. Using standard AES-GCM AEADs allows one to achieve
// the same effect, but gives more control over nonce storage.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_randnonce(void);
// EVP_aead_aes_256_gcm_randnonce is AES-256 in Galois Counter Mode with
// internal nonce generation. The 12-byte nonce is appended to the tag
// and is generated internally. The "tag", for the purpurses of the API, is thus
// 12 bytes larger. The nonce parameter when using this AEAD must be
// zero-length. Since the nonce is random, a single key should not be used for
// more than 2^32 seal operations.
//
// Warning: this is for use for FIPS compliance only. It is probably not
// suitable for other uses. Using standard AES-GCM AEADs allows one to achieve
// the same effect, but gives more control over nonce storage.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_randnonce(void);
// EVP_aead_aes_128_ccm_bluetooth is AES-128-CCM with M=4 and L=2 (4-byte tags
// and 13-byte nonces), as described in the Bluetooth Core Specification v5.0,
// Volume 6, Part E, Section 1.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void);
// EVP_aead_aes_128_ccm_bluetooth_8 is AES-128-CCM with M=8 and L=2 (8-byte tags
// and 13-byte nonces), as used in the Bluetooth Mesh Networking Specification
// v1.0.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void);
// EVP_aead_aes_128_ccm_matter is AES-128-CCM with M=16 and L=2 (16-byte tags
// and 13-byte nonces), as used in the Matter specification.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_matter(void);
// EVP_has_aes_hardware returns one if we enable hardware support for fast and
// constant-time AES-GCM.
OPENSSL_EXPORT int EVP_has_aes_hardware(void);
// EVP_aead_aes_128_eax is AES-128 in EAX mode. Nonce size is either 12 or 16
// bytes, tag length is 16 bytes.
// See https://doi.org/10.1007/978-3-540-25937-4_25.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_eax(void);
// EVP_aead_aes_256_eax is AES-256 in EAX mode. Nonce size is either 12 or 16
// bytes, tag length is 16 bytes.
// See https://doi.org/10.1007/978-3-540-25937-4_25.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_eax(void);
// Utility functions.
// EVP_AEAD_key_length returns the length, in bytes, of the keys used by
// `aead`.
OPENSSL_EXPORT size_t EVP_AEAD_key_length(const EVP_AEAD *aead);
// EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce
// for `aead`.
OPENSSL_EXPORT size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead);
// EVP_AEAD_max_overhead returns the maximum number of additional bytes added
// by the act of sealing data with `aead`.
OPENSSL_EXPORT size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead);
// EVP_AEAD_max_tag_len returns the maximum tag length when using `aead`. This
// is the largest value that can be passed as `tag_len` to
// `EVP_AEAD_CTX_init`.
OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead);
// AEAD operations.
union evp_aead_ctx_st_state {
uint8_t opaque[560];
uint64_t alignment;
};
// An evp_aead_ctx_st (typedefed as `EVP_AEAD_CTX` in base.h) represents an AEAD
// algorithm configured with a specific key and message-independent IV.
struct evp_aead_ctx_st {
const EVP_AEAD *aead;
union evp_aead_ctx_st_state state;
// tag_len may contain the actual length of the authentication tag if it is
// known at initialization time.
uint8_t tag_len;
};
// EVP_AEAD_MAX_KEY_LENGTH contains the maximum key length used by
// any AEAD defined in this header.
#define EVP_AEAD_MAX_KEY_LENGTH 80
// EVP_AEAD_MAX_NONCE_LENGTH contains the maximum nonce length used by
// any AEAD defined in this header.
#define EVP_AEAD_MAX_NONCE_LENGTH 24
// EVP_AEAD_MAX_OVERHEAD contains the maximum overhead used by any AEAD
// defined in this header.
#define EVP_AEAD_MAX_OVERHEAD 64
// EVP_AEAD_MAX_OPEN_OVERHEAD contains the maximum overhead that any AEAD
// defined in this header can remove - even if no AEAD actually generates that
// much, as non-canonical paddings exist (such as in TLS which allows 256 bytes
// padding + 64 bytes MAC).
#define EVP_AEAD_MAX_OPEN_OVERHEAD 320
// EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to
// EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD should
// be used.
#define EVP_AEAD_DEFAULT_TAG_LENGTH 0
// EVP_AEAD_CTX_zero sets an uninitialized `ctx` to the zero state. It must be
// initialized with `EVP_AEAD_CTX_init` before use. It is safe, but not
// necessary, to call `EVP_AEAD_CTX_cleanup` in this state. This may be used for
// more uniform cleanup of `EVP_AEAD_CTX`.
OPENSSL_EXPORT void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx);
// EVP_AEAD_CTX_new allocates an `EVP_AEAD_CTX`, calls `EVP_AEAD_CTX_init` and
// returns the `EVP_AEAD_CTX`, or NULL on error.
OPENSSL_EXPORT EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead,
const uint8_t *key,
size_t key_len, size_t tag_len);
// EVP_AEAD_CTX_free calls `EVP_AEAD_CTX_cleanup` and `OPENSSL_free` on
// `ctx`.
OPENSSL_EXPORT void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx);
// EVP_AEAD_CTX_init initializes `ctx` for the given AEAD algorithm. The `impl`
// argument is ignored and should be NULL. Authentication tags may be truncated
// by passing a size as `tag_len`. A `tag_len` of zero indicates the default
// tag length and this is defined as EVP_AEAD_DEFAULT_TAG_LENGTH for
// readability.
//
// Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In
// the error case, you do not need to call `EVP_AEAD_CTX_cleanup`, but it's
// harmless to do so.
OPENSSL_EXPORT int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const uint8_t *key, size_t key_len,
size_t tag_len, ENGINE *impl);
// EVP_AEAD_CTX_cleanup frees any data allocated by `ctx`. It is a no-op to
// call `EVP_AEAD_CTX_cleanup` on a `EVP_AEAD_CTX` that has been `memset` to
// all zeros.
OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
// EVP_AEAD_CTX_seal encrypts and authenticates `in_len` bytes from `in` and
// authenticates `ad_len` bytes from `ad` and writes the result to `out`. It
// returns one on success and zero otherwise.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// At most `max_out_len` bytes are written to `out` and, in order to ensure
// success, `max_out_len` should be `in_len` plus the result of
// `EVP_AEAD_max_overhead`. On successful return, `*out_len` is set to the
// actual number of bytes written.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_seal` never results in a partial output. If `max_out_len` is
// insufficient, zero will be returned. If any error occurs, `out` will be
// filled with zero bytes and `*out_len` set to zero.
//
// If `in` and `out` alias then `out` must be == `in`.
OPENSSL_EXPORT int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len);
// EVP_AEAD_CTX_open authenticates `in_len` bytes from `in` and `ad_len` bytes
// from `ad` and decrypts at most `in_len` bytes into `out`. It returns one on
// success and zero otherwise.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// At most `in_len` bytes are written to `out`. In order to ensure success,
// `max_out_len` should be at least `in_len`. On successful return, `*out_len`
// is set to the actual number of bytes written.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_open` never results in a partial output. If `max_out_len` is
// insufficient, zero will be returned. If any error occurs, `out` will be
// filled with zero bytes and `*out_len` set to zero.
//
// If `in` and `out` alias then `out` must be == `in`.
OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len);
// EVP_AEAD_CTX_seal_scatter encrypts and authenticates `in_len` bytes from `in`
// and authenticates `ad_len` bytes from `ad`. It writes `in_len` bytes of
// ciphertext to `out` and the authentication tag to `out_tag`. It returns one
// on success and zero otherwise.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// Exactly `in_len` bytes are written to `out`, and up to
// `EVP_AEAD_max_overhead+extra_in_len` bytes to `out_tag`. On successful
// return, `*out_tag_len` is set to the actual number of bytes written to
// `out_tag`.
//
// `extra_in` may point to an additional plaintext input buffer if the cipher
// supports it. If present, `extra_in_len` additional bytes of plaintext are
// encrypted and authenticated, and the ciphertext is written (before the tag)
// to `out_tag`. `max_out_tag_len` must be sized to allow for the additional
// `extra_in_len` bytes.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_seal_scatter` never results in a partial output. If
// `max_out_tag_len` is insufficient, zero will be returned. If any error
// occurs, `out` and `out_tag` will be filled with zero bytes and `*out_tag_len`
// set to zero.
//
// If `in` and `out` alias then `out` must be == `in`. `out_tag` may not alias
// any other argument.
OPENSSL_EXPORT int EVP_AEAD_CTX_seal_scatter(
const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag,
size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce,
size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in,
size_t extra_in_len, const uint8_t *ad, size_t ad_len);
// EVP_AEAD_CTX_open_gather decrypts and authenticates `in_len` bytes from `in`
// and authenticates `ad_len` bytes from `ad` using `in_tag_len` bytes of
// authentication tag from `in_tag`. If successful, it writes `in_len` bytes of
// plaintext to `out`. It returns one on success and zero otherwise.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_open_gather` never results in a partial output. If any error
// occurs, `out` will be filled with zero bytes.
//
// If `in` and `out` alias then `out` must be == `in`.
OPENSSL_EXPORT int EVP_AEAD_CTX_open_gather(
const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce,
size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag,
size_t in_tag_len, const uint8_t *ad, size_t ad_len);
// crypto_ivec_st (aka `CRYPTO_IVEC`) combines a pointer to input data with its
// length. It is usually passed as an array of length of at most
// `CRYPTO_IOVEC_MAX`.
struct crypto_ivec_st {
const uint8_t *in;
size_t len;
};
// crypto_iovec_st (aka `CRYPTO_IOVEC` combines a pointer to input data and a
// pointer to an output buffer with their common length. It is usually passed
// as an array of length of at most `CRYPTO_IOVEC_MAX`.
struct crypto_iovec_st {
// `out` and `in` must be disjoint or equal
uint8_t *out;
const uint8_t *in;
size_t len;
};
// CRYPTO_IOVEC_MAX is the maximum number of entries in an `CRYPTO_IOVEC` or
// `CRYPTO_IVEC` parameter.
#define CRYPTO_IOVEC_MAX 16
// EVP_AEAD_CTX_sealv encrypts and authenticates the `in` bytes from `iovec`
// and authenticates the `aadvec` bytes. It writes the same amount of
// ciphertext to the `out` pointers of `iovec` and the authentication tag to
// `out_tag`. It returns one on success and zero otherwise.
//
// This function computes the same output as `EVP_AEAD_CTX_seal_scatter`, but
// without requiring the input or output to be a contiguous buffer. The
// individual input and output pieces are logically concatenated for a single
// operation; their boundaries are not semantically significant and will not
// impact the output.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// Exactly `len` bytes are written to each `out` member of the `iovec`, and up
// to `EVP_AEAD_max_overhead+extra_in_len` bytes to `out_tag`. On successful
// return, `*out_tag_len` is set to the actual number of bytes written to
// `out_tag`.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_sealv` never results in a partial output. If `max_out_tag_len`
// is insufficient, zero will be returned. If any error occurs, the `out`
// members of the `iovec` and `out_tag` will be filled with zero bytes and
// `*out_tag_len` set to zero.
//
// No output pointer may alias any other pointer passed to this function either
// directly or via `iovec` and `aadvec`, with the one exception that it is
// permitted for the same `iovec` member's `in` and `out` members to be equal
// (in-place operation).
//
// `num_iovec` and `num_aadvec` must be <= `CRYPTO_IOVEC_MAX`.
OPENSSL_EXPORT
int EVP_AEAD_CTX_sealv(const EVP_AEAD_CTX *ctx, const CRYPTO_IOVEC *iovec,
size_t num_iovec, uint8_t *out_tag, size_t *out_tag_len,
size_t max_out_tag_len, const uint8_t *nonce,
size_t nonce_len, const CRYPTO_IVEC *aadvec,
size_t num_aadvec);
// EVP_AEAD_CTX_openv authenticates the `in` bytes from `iovec` and `aadvec`,
// and decrypts the `in` bytes to the `out` pointers of `iovec`. It returns one
// on success and zero otherwise.
//
// This function computes the same output as `EVP_AEAD_CTX_open`, but without
// requiring the input or output to be a contiguous buffer. The individual
// input and output pieces are logically concatenated for a single operation;
// their boundaries are not semantically significant and will not impact the
// output.
//
// This function may (and usually will) output less than the total length of
// `iovec`. In this case, it outputs to a prefix of `iovec`'s output space,
// then returns the length of what was actually written.
//
// In AEADs with a fixed-length authentication tag, the tag is treated as if it
// were appended to the ciphertext, and successful outputs will always be
// exactly the tag length shorter. To open with a separate, detached tag,
// either provide it as a separate `CRYPTO_IOVEC`, or use
// `EVP_AEAD_CTX_openv_detached`. The latter may be more convenient, one does
// not need consider the possibility of output to the final `CRYPTO_IOVEC`.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_openv` never results in a partial output. If any error occurs,
// `out` will be filled with zero bytes and `*out_len` set to zero.
//
// No output pointer may alias any other pointer passed to this function either
// directly or via `iovec` and `aadvec`, with the one exception that it is
// permitted for the same `iovec` member's `in` and `out` members to be equal
// (in-place operation).
//
// `num_iovec` and `num_aadvec` must be <= `CRYPTO_IOVEC_MAX`.
OPENSSL_EXPORT
int EVP_AEAD_CTX_openv(const EVP_AEAD_CTX *ctx, const CRYPTO_IOVEC *iovec,
size_t num_iovec, size_t *out_total_bytes,
const uint8_t *nonce, size_t nonce_len,
const CRYPTO_IVEC *aadvec, size_t num_aadvec);
// EVP_AEAD_CTX_openv_detached authenticates the `in` bytes from `iovec` and
// `aadvec` using `in_tag_len` bytes of authentication tag from `in_tag`. If
// successful, it writes the plaintext of the `in` bytes to the `out` pointers
// of `iovec`. It returns one on success and zero otherwise.
//
// This function is usable with AEADs whose output can be split into a
// ciphertext portion, with the same length as the plaintext, and a
// fixed-length authentication tag. If the AEAD has a variable-length overhead,
// this function will return zero. Such AEADs can only be used with
// `EVP_AEAD_CTX_openv`.
//
// This function computes the same output as `EVP_AEAD_CTX_open`, but with a
// detached tag and without requiring the input or output to be a contiguous
// buffer. The individual input and output pieces are logically concatenated
// for a single operation; their boundaries are not semantically significant
// and will not impact the output.
//
// This function may be called concurrently with itself or any other seal/open
// function on the same `EVP_AEAD_CTX`.
//
// The length of `nonce`, `nonce_len`, must be equal to the result of
// `EVP_AEAD_nonce_length` for this AEAD.
//
// `EVP_AEAD_CTX_openv_detached` never results in a partial output. If any
// error occurs, `out` will be filled with zero bytes.
//
// No output pointer may alias any other pointer passed to this function either
// directly or via `iovec` and `aadvec`, with the one exception that it is
// permitted for the same `iovec` member's `in` and `out` members to be equal
// (in-place operation).
//
// `num_iovec` and `num_aadvec` must be <= `CRYPTO_IOVEC_MAX`.
OPENSSL_EXPORT
int EVP_AEAD_CTX_openv_detached(const EVP_AEAD_CTX *ctx,
const CRYPTO_IOVEC *iovec, size_t num_iovec,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in_tag, size_t in_tag_len,
const CRYPTO_IVEC *aadvec, size_t num_aadvec);
// EVP_AEAD_CTX_aead returns the underlying AEAD for `ctx`, or NULL if one has
// not been set.
OPENSSL_EXPORT const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx);
// TLS-specific AEAD algorithms.
//
// WARNING: These `EVP_AEAD` objects primitives do not meet the definition of
// generic AEADs. They are all specific to TLS and should not be used outside of
// that context. They break the usual guarantees around `EVP_AEAD_CTX`,
// including statefulness, thread-safety, initialization conventions, and
// security requirements around the nonce parameter.
// The following functions implement legacy TLS CBC cipher suites.
//
// WARNING: These functions are effectively internal implementation details of
// libssl, not general-purpose constructions. They are not true AEADs and differ
// from a normal `EVP_AEAD` in many ways:
//
// * They must be initialized with `EVP_AEAD_CTX_init_with_direction`, not
// `EVP_AEAD_CTX_init`.
//
// * The resulting `EVP_AEAD_CTX`s are stateful. Neither `EVP_AEAD_CTX_open*`
// nor `EVP_AEAD_CTX_seal*` can be called concurrently.
//
// * The `ad` parameter must have length 11 (the standard TLS one with length
// omitted).
//
// * The `nonce` parameter is used as a CBC IV and must be unpredictable, not
// just unique.
//
// * The `*_implicit_iv` variants implicitly set the IV to the last block of the
// previous message. They are vulnerable the BEAST attack unless the caller
// applies record-splitting mitigations externally.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void);
// The following functions behave like `EVP_aead_aes_128_gcm` or
// `EVP_aead_aes_256_gcm`, except that seal operations fail if nonces do not
// match the TLS 1.2 or TLS 1.3 nonce construction.
//
// These functions are only applicable for callers that want an extra AEAD-level
// nonce check. `EVP_aead_aes_128_gcm` and `EVP_aead_aes_256_gcm` are otherwise
// suitable for implementing TLS and will produce the same output.
//
// WARNING: `EVP_AEAD_CTX` objects initialized with these `EVP_AEAD`s are
// stateful. `EVP_AEAD_CTX_seal*` cannot be called concurrently.
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls12(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_tls12(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls13(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_tls13(void);
// Obscure functions.
// evp_aead_direction_t denotes the direction of an AEAD operation.
enum evp_aead_direction_t {
evp_aead_open,
evp_aead_seal,
};
// EVP_AEAD_CTX_init_with_direction calls `EVP_AEAD_CTX_init` for normal
// AEADs. For TLS-specific AEADs, it initializes `ctx` for a given direction.
OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction(
EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len,
size_t tag_len, enum evp_aead_direction_t dir);
// EVP_AEAD_CTX_get_iv sets `*out_len` to the length of the IV for `ctx` and
// sets `*out_iv` to point to that many bytes of the current IV. This is only
// meaningful for AEADs with implicit IVs (i.e. CBC mode in TLS 1.0).
//
// It returns one on success or zero on error.
OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
const uint8_t **out_iv, size_t *out_len);
// EVP_AEAD_CTX_tag_len computes the exact byte length of the tag written by
// `EVP_AEAD_CTX_seal_scatter` and writes it to `*out_tag_len`. It returns one
// on success or zero on error. `in_len` and `extra_in_len` must equal the
// arguments of the same names passed to `EVP_AEAD_CTX_seal_scatter`.
//
// To compute the exact byte length of the output written by
// `EVP_AEAD_CTX_seal`, set `extra_in_len` to zero and add `in_len` to the
// result.
//
// To compute the exact byte length of the tag written by `EVP_AEAD_CTX_sealv`,
// set `in_len` to the sum of `len` over the entire `iovec`, and set
// `extra_in_len` to zero.
OPENSSL_EXPORT int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx,
size_t *out_tag_len,
const size_t in_len,
const size_t extra_in_len);
#if defined(__cplusplus)
} // extern C
#if !defined(BORINGSSL_NO_CXX)
extern "C++" {
BSSL_NAMESPACE_BEGIN
using ScopedEVP_AEAD_CTX =
internal::StackAllocated<EVP_AEAD_CTX, void, EVP_AEAD_CTX_zero,
EVP_AEAD_CTX_cleanup>;
BORINGSSL_MAKE_DELETER(EVP_AEAD_CTX, EVP_AEAD_CTX_free)
BSSL_NAMESPACE_END
} // extern C++
#endif
#endif
#endif // OPENSSL_HEADER_AEAD_H