aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/restricted/aws/s2n/crypto/s2n_drbg.c
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/aws/s2n/crypto/s2n_drbg.c')
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_drbg.c456
1 files changed, 228 insertions, 228 deletions
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
index abcd819e04..bd1e78cc47 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
@@ -1,228 +1,228 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file 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.
- */
-
-#include <sys/param.h>
-
-#include <openssl/evp.h>
-
-#include "crypto/s2n_drbg.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_blob.h"
-
-#define s2n_drbg_key_size(drgb) EVP_CIPHER_CTX_key_length((drbg)->ctx)
-#define s2n_drbg_seed_size(drgb) (S2N_DRBG_BLOCK_SIZE + s2n_drbg_key_size(drgb))
-
-/* This function is the same as s2n_increment_sequence_number
- but it does not check for overflow, since overflow is
- acceptable in DRBG */
-int s2n_increment_drbg_counter(struct s2n_blob *counter)
-{
- for (int i = counter->size - 1; i >= 0; i--) {
- counter->data[i] += 1;
- if (counter->data[i]) {
- break;
- }
-
- /* seq[i] wrapped, so let it carry */
- }
- return 0;
-}
-
-static int s2n_drbg_block_encrypt(EVP_CIPHER_CTX * ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE])
-{
- notnull_check(ctx);
- int len = S2N_DRBG_BLOCK_SIZE;
- GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG);
- eq_check(len, S2N_DRBG_BLOCK_SIZE);
-
- return 0;
-}
-
-static int s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
- notnull_check(out);
-
- struct s2n_blob value = {0};
- GUARD(s2n_blob_init(&value, drbg->v, sizeof(drbg->v)));
- int block_aligned_size = out->size - (out->size % S2N_DRBG_BLOCK_SIZE);
-
- /* Per NIST SP800-90A 10.2.1.2: */
- for (int i = 0; i < block_aligned_size; i += S2N_DRBG_BLOCK_SIZE) {
- GUARD(s2n_increment_drbg_counter(&value));
- GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, out->data + i));
- drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
- }
-
- if (out->size <= block_aligned_size) {
- return 0;
- }
-
- uint8_t spare_block[S2N_DRBG_BLOCK_SIZE];
- GUARD(s2n_increment_drbg_counter(&value));
- GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, spare_block));
- drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
-
- memcpy_check(out->data + block_aligned_size, spare_block, out->size - block_aligned_size);
-
- return 0;
-}
-
-static int s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
-
- s2n_stack_blob(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE);
-
- eq_check(provided_data->size, s2n_drbg_seed_size(drbg));
-
- GUARD(s2n_drbg_bits(drbg, &temp_blob));
-
- /* XOR in the provided data */
- for (int i = 0; i < provided_data->size; i++) {
- temp_blob.data[i] ^= provided_data->data[i];
- }
-
- /* Update the key and value */
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, temp_blob.data, NULL), S2N_ERR_DRBG);
-
- memcpy_check(drbg->v, temp_blob.data + s2n_drbg_key_size(drbg), S2N_DRBG_BLOCK_SIZE);
-
- return 0;
-}
-
-static int s2n_drbg_mix_in_entropy(struct s2n_drbg *drbg, struct s2n_blob *entropy, struct s2n_blob *ps)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
- notnull_check(entropy);
-
- gte_check(entropy->size, ps->size);
-
- for (int i = 0; i < ps->size; i++) {
- entropy->data[i] ^= ps->data[i];
- }
-
- GUARD(s2n_drbg_update(drbg, entropy));
-
- return 0;
-}
-
-static int s2n_drbg_seed(struct s2n_drbg *drbg, struct s2n_blob *ps)
-{
- s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- GUARD_AS_POSIX(s2n_get_seed_entropy(&blob));
- GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
-
- drbg->bytes_used = 0;
-
- return 0;
-}
-
-static int s2n_drbg_mix(struct s2n_drbg *drbg, struct s2n_blob *ps)
-{
- s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- GUARD_AS_POSIX(s2n_get_mix_entropy(&blob));
- GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
-
- drbg->mixes += 1;
-
- return 0;
-}
-
-int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode)
-{
- notnull_check(drbg);
-
- drbg->ctx = EVP_CIPHER_CTX_new();
- S2N_ERROR_IF(!drbg->ctx, S2N_ERR_DRBG);
-
- s2n_evp_ctx_init(drbg->ctx);
-
- switch(mode) {
- case S2N_AES_128_CTR_NO_DF_PR:
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_128_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
- break;
- case S2N_AES_256_CTR_NO_DF_PR:
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_256_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
- break;
- default:
- S2N_ERROR(S2N_ERR_DRBG);
- }
-
- lte_check(s2n_drbg_key_size(drbg), S2N_DRBG_MAX_KEY_SIZE);
- lte_check(s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- static const uint8_t zero_key[S2N_DRBG_MAX_KEY_SIZE] = {0};
-
- /* Start off with zeroed data, per 10.2.1.3.1 item 4 and 5 */
- memset(drbg->v, 0, sizeof(drbg->v));
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, zero_key, NULL), S2N_ERR_DRBG);
-
- /* Copy the personalization string */
- s2n_stack_blob(ps, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
- GUARD(s2n_blob_zero(&ps));
-
- memcpy_check(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size));
-
- /* Seed the DRBG */
- GUARD(s2n_drbg_seed(drbg, &ps));
-
- return 0;
-}
-
-int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *blob)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
- s2n_stack_blob(zeros, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- S2N_ERROR_IF(blob->size > S2N_DRBG_GENERATE_LIMIT, S2N_ERR_DRBG_REQUEST_SIZE);
-
- /* Always mix in additional entropy, for prediction resistance */
- GUARD(s2n_drbg_mix(drbg, &zeros));
- GUARD(s2n_drbg_bits(drbg, blob));
- GUARD(s2n_drbg_update(drbg, &zeros));
-
- return 0;
-}
-
-int s2n_drbg_wipe(struct s2n_drbg *drbg)
-{
- notnull_check(drbg);
- if (drbg->ctx) {
- GUARD_OSSL(EVP_CIPHER_CTX_cleanup(drbg->ctx), S2N_ERR_DRBG);
-
- EVP_CIPHER_CTX_free(drbg->ctx);
- drbg->ctx = NULL;
- }
-
- *drbg = (struct s2n_drbg) {0};
- return 0;
-}
-
-int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used)
-{
- notnull_check(drbg);
- notnull_check(bytes_used);
- *bytes_used = drbg->bytes_used;
- return 0;
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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.
+ */
+
+#include <sys/param.h>
+
+#include <openssl/evp.h>
+
+#include "crypto/s2n_drbg.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_blob.h"
+
+#define s2n_drbg_key_size(drgb) EVP_CIPHER_CTX_key_length((drbg)->ctx)
+#define s2n_drbg_seed_size(drgb) (S2N_DRBG_BLOCK_SIZE + s2n_drbg_key_size(drgb))
+
+/* This function is the same as s2n_increment_sequence_number
+ but it does not check for overflow, since overflow is
+ acceptable in DRBG */
+int s2n_increment_drbg_counter(struct s2n_blob *counter)
+{
+ for (int i = counter->size - 1; i >= 0; i--) {
+ counter->data[i] += 1;
+ if (counter->data[i]) {
+ break;
+ }
+
+ /* seq[i] wrapped, so let it carry */
+ }
+ return 0;
+}
+
+static int s2n_drbg_block_encrypt(EVP_CIPHER_CTX * ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE])
+{
+ notnull_check(ctx);
+ int len = S2N_DRBG_BLOCK_SIZE;
+ GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG);
+ eq_check(len, S2N_DRBG_BLOCK_SIZE);
+
+ return 0;
+}
+
+static int s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+ notnull_check(out);
+
+ struct s2n_blob value = {0};
+ GUARD(s2n_blob_init(&value, drbg->v, sizeof(drbg->v)));
+ int block_aligned_size = out->size - (out->size % S2N_DRBG_BLOCK_SIZE);
+
+ /* Per NIST SP800-90A 10.2.1.2: */
+ for (int i = 0; i < block_aligned_size; i += S2N_DRBG_BLOCK_SIZE) {
+ GUARD(s2n_increment_drbg_counter(&value));
+ GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, out->data + i));
+ drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
+ }
+
+ if (out->size <= block_aligned_size) {
+ return 0;
+ }
+
+ uint8_t spare_block[S2N_DRBG_BLOCK_SIZE];
+ GUARD(s2n_increment_drbg_counter(&value));
+ GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, spare_block));
+ drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
+
+ memcpy_check(out->data + block_aligned_size, spare_block, out->size - block_aligned_size);
+
+ return 0;
+}
+
+static int s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+
+ s2n_stack_blob(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE);
+
+ eq_check(provided_data->size, s2n_drbg_seed_size(drbg));
+
+ GUARD(s2n_drbg_bits(drbg, &temp_blob));
+
+ /* XOR in the provided data */
+ for (int i = 0; i < provided_data->size; i++) {
+ temp_blob.data[i] ^= provided_data->data[i];
+ }
+
+ /* Update the key and value */
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, temp_blob.data, NULL), S2N_ERR_DRBG);
+
+ memcpy_check(drbg->v, temp_blob.data + s2n_drbg_key_size(drbg), S2N_DRBG_BLOCK_SIZE);
+
+ return 0;
+}
+
+static int s2n_drbg_mix_in_entropy(struct s2n_drbg *drbg, struct s2n_blob *entropy, struct s2n_blob *ps)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+ notnull_check(entropy);
+
+ gte_check(entropy->size, ps->size);
+
+ for (int i = 0; i < ps->size; i++) {
+ entropy->data[i] ^= ps->data[i];
+ }
+
+ GUARD(s2n_drbg_update(drbg, entropy));
+
+ return 0;
+}
+
+static int s2n_drbg_seed(struct s2n_drbg *drbg, struct s2n_blob *ps)
+{
+ s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ GUARD_AS_POSIX(s2n_get_seed_entropy(&blob));
+ GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
+
+ drbg->bytes_used = 0;
+
+ return 0;
+}
+
+static int s2n_drbg_mix(struct s2n_drbg *drbg, struct s2n_blob *ps)
+{
+ s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ GUARD_AS_POSIX(s2n_get_mix_entropy(&blob));
+ GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
+
+ drbg->mixes += 1;
+
+ return 0;
+}
+
+int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode)
+{
+ notnull_check(drbg);
+
+ drbg->ctx = EVP_CIPHER_CTX_new();
+ S2N_ERROR_IF(!drbg->ctx, S2N_ERR_DRBG);
+
+ s2n_evp_ctx_init(drbg->ctx);
+
+ switch(mode) {
+ case S2N_AES_128_CTR_NO_DF_PR:
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_128_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
+ break;
+ case S2N_AES_256_CTR_NO_DF_PR:
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_256_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_DRBG);
+ }
+
+ lte_check(s2n_drbg_key_size(drbg), S2N_DRBG_MAX_KEY_SIZE);
+ lte_check(s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ static const uint8_t zero_key[S2N_DRBG_MAX_KEY_SIZE] = {0};
+
+ /* Start off with zeroed data, per 10.2.1.3.1 item 4 and 5 */
+ memset(drbg->v, 0, sizeof(drbg->v));
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, zero_key, NULL), S2N_ERR_DRBG);
+
+ /* Copy the personalization string */
+ s2n_stack_blob(ps, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+ GUARD(s2n_blob_zero(&ps));
+
+ memcpy_check(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size));
+
+ /* Seed the DRBG */
+ GUARD(s2n_drbg_seed(drbg, &ps));
+
+ return 0;
+}
+
+int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *blob)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+ s2n_stack_blob(zeros, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ S2N_ERROR_IF(blob->size > S2N_DRBG_GENERATE_LIMIT, S2N_ERR_DRBG_REQUEST_SIZE);
+
+ /* Always mix in additional entropy, for prediction resistance */
+ GUARD(s2n_drbg_mix(drbg, &zeros));
+ GUARD(s2n_drbg_bits(drbg, blob));
+ GUARD(s2n_drbg_update(drbg, &zeros));
+
+ return 0;
+}
+
+int s2n_drbg_wipe(struct s2n_drbg *drbg)
+{
+ notnull_check(drbg);
+ if (drbg->ctx) {
+ GUARD_OSSL(EVP_CIPHER_CTX_cleanup(drbg->ctx), S2N_ERR_DRBG);
+
+ EVP_CIPHER_CTX_free(drbg->ctx);
+ drbg->ctx = NULL;
+ }
+
+ *drbg = (struct s2n_drbg) {0};
+ return 0;
+}
+
+int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used)
+{
+ notnull_check(drbg);
+ notnull_check(bytes_used);
+ *bytes_used = drbg->bytes_used;
+ return 0;
+}