mirror of
https://github.com/AntelopeIO/boringssl.git
synced 2026-07-21 14:43:53 +00:00
df9955b62d
The assembly functions from OpenSSL vary in how the counter overflow works. The aarch64 implementation uses a mix of 32-bit and 64-bit counters. This is because, when packing a block into 64-bit general-purpose registers, it is easier to implement a 64-bit counter than a 32-bit one. Whereas, on 32-bit general-purpose registers, or when using vector registers with 32-bit lanes, it is easier to implement a 32-bit counter. Counters will never overflow with the AEAD, which sets the length limit so it never happens. (Failing to do so will reuse a key/nonce/counter triple.) RFC 8439 is silent on what happens on overflow, so at best one can say it is implicitly undefined behavior. This came about because pyca/cryptography reportedly exposed a ChaCha20 API which encouraged callers to randomize the starting counter. Wrapping with a randomized starting counter isn't inherently wrong, though it is pointless and goes against how the spec recommends using the initial counter value. Nonetheless, we would prefer our functions behave consistently across platforms, rather than silently give ill-defined output given some inputs. So, normalize the behavior to the wrapping version in CRYPTO_chacha_20 by dividing up into multiple ChaCha20_ctr32 calls as needed. Fixed: 614 Change-Id: I191461f25753b9f6b59064c6c08cd4299085e172 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60387 Commit-Queue: Adam Langley <agl@google.com> Auto-Submit: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
48 lines
1.9 KiB
C
48 lines
1.9 KiB
C
/* Copyright (c) 2014, Google Inc.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
#ifndef OPENSSL_HEADER_CHACHA_H
|
|
#define OPENSSL_HEADER_CHACHA_H
|
|
|
|
#include <openssl/base.h>
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
// ChaCha20.
|
|
//
|
|
// ChaCha20 is a stream cipher. See https://tools.ietf.org/html/rfc8439.
|
|
|
|
|
|
// CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and
|
|
// nonce and writes the result to |out|. If |in| and |out| alias, they must be
|
|
// equal. The initial block counter is specified by |counter|.
|
|
//
|
|
// This function implements a 32-bit block counter as in RFC 8439. On overflow,
|
|
// the counter wraps. Reusing a key, nonce, and block counter combination is not
|
|
// secure, so wrapping is usually a bug in the caller. While it is possible to
|
|
// wrap without reuse with a large initial block counter, this is not
|
|
// recommended and may not be portable to other ChaCha20 implementations.
|
|
OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
|
|
size_t in_len, const uint8_t key[32],
|
|
const uint8_t nonce[12], uint32_t counter);
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
} // extern C
|
|
#endif
|
|
|
|
#endif // OPENSSL_HEADER_CHACHA_H
|