aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/utils
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/utils
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/utils')
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_annotations.h38
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_array.c392
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_array.h90
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_asn1_time.c578
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_asn1_time.h74
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_bitmap.h44
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_blob.c252
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_blob.h134
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_compiler.h48
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_ensure.c54
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_ensure.h140
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_init.c166
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_map.c480
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_map.h66
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_map_internal.h72
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_mem.c608
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_mem.h62
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_random.c1096
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_random.h68
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_result.c186
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_result.h96
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_rfc5952.c270
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_rfc5952.h48
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_safety.c468
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_safety.h816
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_set.c294
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_set.h66
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_socket.c452
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_socket.h106
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_str.c98
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_str.h34
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_timer.c98
-rw-r--r--contrib/restricted/aws/s2n/utils/s2n_timer.h54
33 files changed, 3774 insertions, 3774 deletions
diff --git a/contrib/restricted/aws/s2n/utils/s2n_annotations.h b/contrib/restricted/aws/s2n/utils/s2n_annotations.h
index 4a004c92a1..245f434d96 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_annotations.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_annotations.h
@@ -1,19 +1,19 @@
-/*
- * 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.
- */
-#pragma once
-
-/* For compilation purposes, these annotations are no-ops */
-#define S2N_PUBLIC_INPUT(__a)
-#define S2N_INVARIENT(__a)
+/*
+ * 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.
+ */
+#pragma once
+
+/* For compilation purposes, these annotations are no-ops */
+#define S2N_PUBLIC_INPUT(__a)
+#define S2N_INVARIENT(__a)
diff --git a/contrib/restricted/aws/s2n/utils/s2n_array.c b/contrib/restricted/aws/s2n/utils/s2n_array.c
index ecdf9a2cf2..0f4837193c 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_array.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_array.c
@@ -1,196 +1,196 @@
-/*
- * 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 "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_array.h"
-
-S2N_RESULT s2n_array_validate(const struct s2n_array *array)
-{
- uint32_t mem_size = 0;
- ENSURE_REF(array);
- GUARD_RESULT(s2n_blob_validate(&array->mem));
- ENSURE_NE(array->element_size, 0);
- GUARD_AS_RESULT(s2n_mul_overflow(array->len, array->element_size, &mem_size));
- ENSURE_GTE(array->mem.size, mem_size);
- return S2N_RESULT_OK;
-}
-
-static S2N_RESULT s2n_array_enlarge(struct s2n_array *array, uint32_t capacity)
-{
- ENSURE_REF(array);
-
- /* Acquire the memory */
- uint32_t mem_needed;
- GUARD_AS_RESULT(s2n_mul_overflow(array->element_size, capacity, &mem_needed));
- GUARD_AS_RESULT(s2n_realloc(&array->mem, mem_needed));
-
- /* Zero the extened part */
- uint32_t array_elements_size;
- GUARD_AS_RESULT(s2n_mul_overflow(array->element_size, array->len, &array_elements_size));
- CHECKED_MEMSET(array->mem.data + array_elements_size, 0, array->mem.size - array_elements_size);
- GUARD_RESULT(s2n_array_validate(array));
- return S2N_RESULT_OK;
-}
-
-struct s2n_array *s2n_array_new(uint32_t element_size)
-{
- struct s2n_blob mem = {0};
- GUARD_PTR(s2n_alloc(&mem, sizeof(struct s2n_array)));
-
- struct s2n_array *array = (void *) mem.data;
-
- *array = (struct s2n_array) {.mem = {0}, .len = 0, .element_size = element_size};
-
- if (s2n_result_is_error(s2n_array_enlarge(array, S2N_INITIAL_ARRAY_SIZE))) {
- /* Avoid memory leak if allocation fails */
- GUARD_PTR(s2n_free(&mem));
- return NULL;
- }
- return array;
-}
-
-S2N_RESULT s2n_array_init(struct s2n_array *array, uint32_t element_size)
-{
- ENSURE_REF(array);
-
- *array = (struct s2n_array){.element_size = element_size};
-
- GUARD_RESULT(s2n_array_validate(array));
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_pushback(struct s2n_array *array, void **element)
-{
- GUARD_RESULT(s2n_array_validate(array));
- ENSURE_REF(element);
- return s2n_array_insert(array, array->len, element);
-}
-
-S2N_RESULT s2n_array_get(struct s2n_array *array, uint32_t index, void **element)
-{
- GUARD_RESULT(s2n_array_validate(array));
- ENSURE_REF(element);
- ENSURE(index < array->len, S2N_ERR_ARRAY_INDEX_OOB);
- *element = array->mem.data + (array->element_size * index);
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_insert_and_copy(struct s2n_array *array, uint32_t index, void* element)
-{
- void* insert_location = NULL;
- GUARD_RESULT(s2n_array_insert(array, index, &insert_location));
- CHECKED_MEMCPY(insert_location, element, array->element_size);
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t index, void **element)
-{
- GUARD_RESULT(s2n_array_validate(array));
- ENSURE_REF(element);
- /* index == len is ok since we're about to add one element */
- ENSURE(index <= array->len, S2N_ERR_ARRAY_INDEX_OOB);
-
- /* We are about to add one more element to the array. Add capacity if necessary */
- uint32_t current_capacity = 0;
- GUARD_RESULT(s2n_array_capacity(array, &current_capacity));
-
- if (array->len >= current_capacity) {
- /* Enlarge the array */
- uint32_t new_capacity = 0;
- GUARD_AS_RESULT(s2n_mul_overflow(current_capacity, 2, &new_capacity));
- new_capacity = MAX(new_capacity, S2N_INITIAL_ARRAY_SIZE);
- GUARD_RESULT(s2n_array_enlarge(array, new_capacity));
- }
-
- /* If we are adding at an existing index, slide everything down. */
- if (index < array->len) {
- memmove(array->mem.data + array->element_size * (index + 1),
- array->mem.data + array->element_size * index,
- (array->len - index) * array->element_size);
- }
-
- *element = array->mem.data + array->element_size * index;
- array->len++;
-
- GUARD_RESULT(s2n_array_validate(array));
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_remove(struct s2n_array *array, uint32_t index)
-{
- GUARD_RESULT(s2n_array_validate(array));
- ENSURE(index < array->len, S2N_ERR_ARRAY_INDEX_OOB);
-
- /* If the removed element is the last one, no need to move anything.
- * Otherwise, shift everything down */
- if (index != array->len - 1) {
- memmove(array->mem.data + array->element_size * index,
- array->mem.data + array->element_size * (index + 1),
- (array->len - index - 1) * array->element_size);
- }
- array->len--;
-
- /* After shifting, zero the last element */
- CHECKED_MEMSET(array->mem.data + array->element_size * array->len,
- 0,
- array->element_size);
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_num_elements(struct s2n_array *array, uint32_t *len)
-{
- GUARD_RESULT(s2n_array_validate(array));
- ENSURE_MUT(len);
-
- *len = array->len;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_capacity(struct s2n_array *array, uint32_t *capacity)
-{
- GUARD_RESULT(s2n_array_validate(array));
- ENSURE_MUT(capacity);
-
- *capacity = array->mem.size / array->element_size;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_free_p(struct s2n_array **parray)
-{
- ENSURE_REF(parray);
- struct s2n_array *array = *parray;
-
- ENSURE_REF(array);
- /* Free the elements */
- GUARD_AS_RESULT(s2n_free(&array->mem));
-
- /* And finally the array */
- GUARD_AS_RESULT(s2n_free_object((uint8_t **)parray, sizeof(struct s2n_array)));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_array_free(struct s2n_array *array)
-{
- ENSURE_REF(array);
- return s2n_array_free_p(&array);
-}
+/*
+ * 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 "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_array.h"
+
+S2N_RESULT s2n_array_validate(const struct s2n_array *array)
+{
+ uint32_t mem_size = 0;
+ ENSURE_REF(array);
+ GUARD_RESULT(s2n_blob_validate(&array->mem));
+ ENSURE_NE(array->element_size, 0);
+ GUARD_AS_RESULT(s2n_mul_overflow(array->len, array->element_size, &mem_size));
+ ENSURE_GTE(array->mem.size, mem_size);
+ return S2N_RESULT_OK;
+}
+
+static S2N_RESULT s2n_array_enlarge(struct s2n_array *array, uint32_t capacity)
+{
+ ENSURE_REF(array);
+
+ /* Acquire the memory */
+ uint32_t mem_needed;
+ GUARD_AS_RESULT(s2n_mul_overflow(array->element_size, capacity, &mem_needed));
+ GUARD_AS_RESULT(s2n_realloc(&array->mem, mem_needed));
+
+ /* Zero the extened part */
+ uint32_t array_elements_size;
+ GUARD_AS_RESULT(s2n_mul_overflow(array->element_size, array->len, &array_elements_size));
+ CHECKED_MEMSET(array->mem.data + array_elements_size, 0, array->mem.size - array_elements_size);
+ GUARD_RESULT(s2n_array_validate(array));
+ return S2N_RESULT_OK;
+}
+
+struct s2n_array *s2n_array_new(uint32_t element_size)
+{
+ struct s2n_blob mem = {0};
+ GUARD_PTR(s2n_alloc(&mem, sizeof(struct s2n_array)));
+
+ struct s2n_array *array = (void *) mem.data;
+
+ *array = (struct s2n_array) {.mem = {0}, .len = 0, .element_size = element_size};
+
+ if (s2n_result_is_error(s2n_array_enlarge(array, S2N_INITIAL_ARRAY_SIZE))) {
+ /* Avoid memory leak if allocation fails */
+ GUARD_PTR(s2n_free(&mem));
+ return NULL;
+ }
+ return array;
+}
+
+S2N_RESULT s2n_array_init(struct s2n_array *array, uint32_t element_size)
+{
+ ENSURE_REF(array);
+
+ *array = (struct s2n_array){.element_size = element_size};
+
+ GUARD_RESULT(s2n_array_validate(array));
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_pushback(struct s2n_array *array, void **element)
+{
+ GUARD_RESULT(s2n_array_validate(array));
+ ENSURE_REF(element);
+ return s2n_array_insert(array, array->len, element);
+}
+
+S2N_RESULT s2n_array_get(struct s2n_array *array, uint32_t index, void **element)
+{
+ GUARD_RESULT(s2n_array_validate(array));
+ ENSURE_REF(element);
+ ENSURE(index < array->len, S2N_ERR_ARRAY_INDEX_OOB);
+ *element = array->mem.data + (array->element_size * index);
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_insert_and_copy(struct s2n_array *array, uint32_t index, void* element)
+{
+ void* insert_location = NULL;
+ GUARD_RESULT(s2n_array_insert(array, index, &insert_location));
+ CHECKED_MEMCPY(insert_location, element, array->element_size);
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t index, void **element)
+{
+ GUARD_RESULT(s2n_array_validate(array));
+ ENSURE_REF(element);
+ /* index == len is ok since we're about to add one element */
+ ENSURE(index <= array->len, S2N_ERR_ARRAY_INDEX_OOB);
+
+ /* We are about to add one more element to the array. Add capacity if necessary */
+ uint32_t current_capacity = 0;
+ GUARD_RESULT(s2n_array_capacity(array, &current_capacity));
+
+ if (array->len >= current_capacity) {
+ /* Enlarge the array */
+ uint32_t new_capacity = 0;
+ GUARD_AS_RESULT(s2n_mul_overflow(current_capacity, 2, &new_capacity));
+ new_capacity = MAX(new_capacity, S2N_INITIAL_ARRAY_SIZE);
+ GUARD_RESULT(s2n_array_enlarge(array, new_capacity));
+ }
+
+ /* If we are adding at an existing index, slide everything down. */
+ if (index < array->len) {
+ memmove(array->mem.data + array->element_size * (index + 1),
+ array->mem.data + array->element_size * index,
+ (array->len - index) * array->element_size);
+ }
+
+ *element = array->mem.data + array->element_size * index;
+ array->len++;
+
+ GUARD_RESULT(s2n_array_validate(array));
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_remove(struct s2n_array *array, uint32_t index)
+{
+ GUARD_RESULT(s2n_array_validate(array));
+ ENSURE(index < array->len, S2N_ERR_ARRAY_INDEX_OOB);
+
+ /* If the removed element is the last one, no need to move anything.
+ * Otherwise, shift everything down */
+ if (index != array->len - 1) {
+ memmove(array->mem.data + array->element_size * index,
+ array->mem.data + array->element_size * (index + 1),
+ (array->len - index - 1) * array->element_size);
+ }
+ array->len--;
+
+ /* After shifting, zero the last element */
+ CHECKED_MEMSET(array->mem.data + array->element_size * array->len,
+ 0,
+ array->element_size);
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_num_elements(struct s2n_array *array, uint32_t *len)
+{
+ GUARD_RESULT(s2n_array_validate(array));
+ ENSURE_MUT(len);
+
+ *len = array->len;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_capacity(struct s2n_array *array, uint32_t *capacity)
+{
+ GUARD_RESULT(s2n_array_validate(array));
+ ENSURE_MUT(capacity);
+
+ *capacity = array->mem.size / array->element_size;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_free_p(struct s2n_array **parray)
+{
+ ENSURE_REF(parray);
+ struct s2n_array *array = *parray;
+
+ ENSURE_REF(array);
+ /* Free the elements */
+ GUARD_AS_RESULT(s2n_free(&array->mem));
+
+ /* And finally the array */
+ GUARD_AS_RESULT(s2n_free_object((uint8_t **)parray, sizeof(struct s2n_array)));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_array_free(struct s2n_array *array)
+{
+ ENSURE_REF(array);
+ return s2n_array_free_p(&array);
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_array.h b/contrib/restricted/aws/s2n/utils/s2n_array.h
index 3ae0996948..bf48b3aaac 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_array.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_array.h
@@ -1,45 +1,45 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <s2n.h>
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-#define S2N_INITIAL_ARRAY_SIZE 16
-
-struct s2n_array {
- /* Pointer to elements in array */
- struct s2n_blob mem;
-
- /* The total number of elements currently in the array. */
- uint32_t len;
-
- /* The size of each element in the array */
- uint32_t element_size;
-};
-
-extern S2N_RESULT s2n_array_validate(const struct s2n_array *array);
-extern struct s2n_array *s2n_array_new(uint32_t element_size);
-extern S2N_RESULT s2n_array_init(struct s2n_array *array, uint32_t element_size);
-extern S2N_RESULT s2n_array_pushback(struct s2n_array *array, void **element);
-extern S2N_RESULT s2n_array_get(struct s2n_array *array, uint32_t index, void **element);
-extern S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t index, void **element);
-extern S2N_RESULT s2n_array_insert_and_copy(struct s2n_array *array, uint32_t index, void *element);
-extern S2N_RESULT s2n_array_num_elements(struct s2n_array *array, uint32_t *len);
-extern S2N_RESULT s2n_array_capacity(struct s2n_array *array, uint32_t *capacity);
-extern S2N_RESULT s2n_array_remove(struct s2n_array *array, uint32_t index);
-extern S2N_RESULT s2n_array_free_p(struct s2n_array **parray);
-extern S2N_RESULT s2n_array_free(struct s2n_array *array);
+/*
+ * 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.
+ */
+#pragma once
+
+#include <s2n.h>
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+#define S2N_INITIAL_ARRAY_SIZE 16
+
+struct s2n_array {
+ /* Pointer to elements in array */
+ struct s2n_blob mem;
+
+ /* The total number of elements currently in the array. */
+ uint32_t len;
+
+ /* The size of each element in the array */
+ uint32_t element_size;
+};
+
+extern S2N_RESULT s2n_array_validate(const struct s2n_array *array);
+extern struct s2n_array *s2n_array_new(uint32_t element_size);
+extern S2N_RESULT s2n_array_init(struct s2n_array *array, uint32_t element_size);
+extern S2N_RESULT s2n_array_pushback(struct s2n_array *array, void **element);
+extern S2N_RESULT s2n_array_get(struct s2n_array *array, uint32_t index, void **element);
+extern S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t index, void **element);
+extern S2N_RESULT s2n_array_insert_and_copy(struct s2n_array *array, uint32_t index, void *element);
+extern S2N_RESULT s2n_array_num_elements(struct s2n_array *array, uint32_t *len);
+extern S2N_RESULT s2n_array_capacity(struct s2n_array *array, uint32_t *capacity);
+extern S2N_RESULT s2n_array_remove(struct s2n_array *array, uint32_t index);
+extern S2N_RESULT s2n_array_free_p(struct s2n_array **parray);
+extern S2N_RESULT s2n_array_free(struct s2n_array *array);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_asn1_time.c b/contrib/restricted/aws/s2n/utils/s2n_asn1_time.c
index 01b7acceb1..3acaaa41f5 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_asn1_time.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_asn1_time.c
@@ -1,289 +1,289 @@
-/*
- * 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 "utils/s2n_asn1_time.h"
-#include "utils/s2n_result.h"
-#include "utils/s2n_safety.h"
-
-#include <time.h>
-#include <ctype.h>
-
-typedef enum parser_state {
- ON_YEAR_DIGIT_1 = 0,
- ON_YEAR_DIGIT_2,
- ON_YEAR_DIGIT_3,
- ON_YEAR_DIGIT_4,
- ON_MONTH_DIGIT_1,
- ON_MONTH_DIGIT_2,
- ON_DAY_DIGIT_1,
- ON_DAY_DIGIT_2,
- ON_HOUR_DIGIT_1,
- ON_HOUR_DIGIT_2,
- ON_MINUTE_DIGIT_1,
- ON_MINUTE_DIGIT_2,
- ON_SECOND_DIGIT_1,
- ON_SECOND_DIGIT_2,
- ON_SUBSECOND,
- ON_TIMEZONE,
- ON_OFFSET_HOURS_DIGIT_1,
- ON_OFFSET_HOURS_DIGIT_2,
- ON_OFFSET_MINUTES_DIGIT_1,
- ON_OFFSET_MINUTES_DIGIT_2,
- FINISHED,
- PARSE_ERROR
-} parser_state;
-
-static inline long get_gmt_offset(struct tm *t) {
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__ANDROID__) || defined(ANDROID) || defined(__APPLE__) && defined(__MACH__)
- return t->tm_gmtoff;
-#else
- return t->tm_gmtoff;
-#endif
-}
-
-static inline void get_current_timesettings(long *gmt_offset, int *is_dst) {
- struct tm time_ptr = {0};
- time_t raw_time;
- time(&raw_time);
- localtime_r(&raw_time, &time_ptr);
- *gmt_offset = get_gmt_offset(&time_ptr);
- *is_dst = time_ptr.tm_isdst;
-}
-
-#define PARSE_DIGIT(c, d) do { ENSURE(isdigit(c), S2N_ERR_SAFETY); d = c - '0'; } while(0)
-
-/* this is just a standard state machine for ASN1 date format... nothing special.
- * just do a character at a time and change the state per character encountered.
- * when finished the above time structure should be filled in along with some
- * crazy timezone info we'll need shortly afterwards.*/
-static S2N_RESULT process_state(parser_state *state, char current_char, struct parser_args *args) {
- switch (*state) {
- case ON_YEAR_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_year = args->current_digit;
- *state = ON_YEAR_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_YEAR_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_year = args->time.tm_year * 10 + args->current_digit;
- *state = ON_YEAR_DIGIT_3;
- return S2N_RESULT_OK;
- case ON_YEAR_DIGIT_3:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_year = args->time.tm_year * 10 + args->current_digit;
- *state = ON_YEAR_DIGIT_4;
- return S2N_RESULT_OK;
- case ON_YEAR_DIGIT_4:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_year = args->time.tm_year * 10 + args->current_digit;
- args->time.tm_year -= 1900;
- if (args->time.tm_year < 0) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_MONTH_DIGIT_1;
- return S2N_RESULT_OK;
- case ON_MONTH_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_mon = args->current_digit;
- *state = ON_MONTH_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_MONTH_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_mon = args->time.tm_mon * 10 + args->current_digit;
- args->time.tm_mon -= 1;
-
- if (args->time.tm_mon < 0 || args->time.tm_mon > 11) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_DAY_DIGIT_1;
- return S2N_RESULT_OK;
- case ON_DAY_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_mday = args->current_digit;
- *state = ON_DAY_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_DAY_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_mday = args->time.tm_mday * 10 + args->current_digit;
-
- if (args->time.tm_mday < 0 || args->time.tm_mday > 31) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_HOUR_DIGIT_1;
- return S2N_RESULT_OK;
- case ON_HOUR_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_hour = args->current_digit;
- *state = ON_HOUR_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_HOUR_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_hour = args->time.tm_hour * 10 + args->current_digit;
-
- if (args->time.tm_hour < 0 || args->time.tm_hour > 23) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_MINUTE_DIGIT_1;
- return S2N_RESULT_OK;
- case ON_MINUTE_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_min = args->current_digit;
- *state = ON_MINUTE_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_MINUTE_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_min = args->time.tm_min * 10 + args->current_digit;
-
- if (args->time.tm_min < 0 || args->time.tm_min > 59) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_SECOND_DIGIT_1;
- return S2N_RESULT_OK;
- case ON_SECOND_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_sec = args->current_digit;
- *state = ON_SECOND_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_SECOND_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->time.tm_sec = args->time.tm_sec * 10 + args->current_digit;
-
- if (args->time.tm_sec < 0 || args->time.tm_sec > 59) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_SUBSECOND;
- return S2N_RESULT_OK;
- case ON_SUBSECOND:
- if (current_char == '.' || isdigit(current_char)) {
- *state = ON_SUBSECOND;
- return S2N_RESULT_OK;
- }
- FALL_THROUGH;
- case ON_TIMEZONE:
- if (current_char == 'Z' || current_char == 'z') {
- args->local_time_assumed = 0;
- *state = FINISHED;
- return S2N_RESULT_OK;
- } else if (current_char == '-') {
- args->local_time_assumed = 0;
- args->offset_negative = 1;
- *state = ON_OFFSET_HOURS_DIGIT_1;
- return S2N_RESULT_OK;
- } else if (current_char == '+') {
- args->local_time_assumed = 0;
- args->offset_negative = 0;
- *state = ON_OFFSET_HOURS_DIGIT_1;
- return S2N_RESULT_OK;
- }
-
- return S2N_RESULT_ERROR;
- case ON_OFFSET_HOURS_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->offset_hours = args->current_digit;
- *state = ON_OFFSET_HOURS_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_OFFSET_HOURS_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->offset_hours = args->offset_hours * 10 + args->current_digit;
-
- if (args->offset_hours < 0 || args->offset_hours > 23) {
- return S2N_RESULT_ERROR;
- }
-
- *state = ON_OFFSET_MINUTES_DIGIT_1;
- return S2N_RESULT_OK;
- case ON_OFFSET_MINUTES_DIGIT_1:
- PARSE_DIGIT(current_char, args->current_digit);
- args->offset_minutes = args->current_digit;
- *state = ON_OFFSET_MINUTES_DIGIT_2;
- return S2N_RESULT_OK;
- case ON_OFFSET_MINUTES_DIGIT_2:
- PARSE_DIGIT(current_char, args->current_digit);
- args->offset_minutes = args->offset_minutes * 10 + args->current_digit;
-
- if (args->offset_minutes < 0 || args->offset_minutes > 23) {
- return S2N_RESULT_ERROR;
- }
-
- *state = FINISHED;
- return S2N_RESULT_OK;
- default:
- return S2N_RESULT_ERROR;
- }
-}
-
-S2N_RESULT s2n_asn1_time_to_nano_since_epoch_ticks(const char *asn1_time, uint32_t len, uint64_t *ticks) {
-
- /* figure out if we are on something other than UTC since timegm is not supported everywhere. */
- long gmt_offset_current = 0;
- int is_dst = 0;
- get_current_timesettings(&gmt_offset_current, &is_dst);
-
- uint32_t str_len = len;
- parser_state state = ON_YEAR_DIGIT_1;
-
- struct parser_args args = {
- .time = {.tm_hour = 0, .tm_isdst = -1, .tm_mday = 0, .tm_min = 0, .tm_mon = 0,
- .tm_sec = 0, .tm_wday = 0, .tm_yday = 0, .tm_year = 0,
- },
- .current_digit = 0,
- .local_time_assumed = 1,
- .offset_hours = 0,
- .offset_minutes = 0,
- .offset_negative = 0
- };
-
- size_t current_pos = 0;
-
- while (state < FINISHED && current_pos < str_len) {
- char current_char = asn1_time[current_pos];
- ENSURE_OK(process_state(&state, current_char, &args), S2N_ERR_INVALID_ARGUMENT);
- current_pos++;
- }
-
- /* state on subsecond means no timezone info was found and we assume local time */
- ENSURE(state == FINISHED || state == ON_SUBSECOND, S2N_ERR_INVALID_ARGUMENT);
-
- time_t clock_data = mktime(&args.time);
- ENSURE_GTE(clock_data, 0);
-
- /* ASN1 + and - is in format HHMM. We need to convert it to seconds for the adjustment */
- long gmt_offset = (args.offset_hours * 3600) + (args.offset_minutes * 60);
-
- if (args.offset_negative) {
- gmt_offset = 0 - gmt_offset;
- }
-
- /* if we detected UTC is being used (please always use UTC), we need to add the detected timezone on the local
- * machine back to the offset. Also, the offset includes an offset for daylight savings time. When the time being parsed
- * and the local time are on different sides of the dst barrier, the offset has to be adjusted to account for it. */
- if (!args.local_time_assumed) {
- gmt_offset -= gmt_offset_current;
- gmt_offset -= args.time.tm_isdst != is_dst ? (args.time.tm_isdst - is_dst) * 3600 : 0;
- }
-
- ENSURE_GTE(clock_data, gmt_offset);
-
- /* convert to nanoseconds and add the timezone offset. */
- *ticks = ((uint64_t) clock_data - gmt_offset) * 1000000000;
- return S2N_RESULT_OK;
-}
-
+/*
+ * 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 "utils/s2n_asn1_time.h"
+#include "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+
+#include <time.h>
+#include <ctype.h>
+
+typedef enum parser_state {
+ ON_YEAR_DIGIT_1 = 0,
+ ON_YEAR_DIGIT_2,
+ ON_YEAR_DIGIT_3,
+ ON_YEAR_DIGIT_4,
+ ON_MONTH_DIGIT_1,
+ ON_MONTH_DIGIT_2,
+ ON_DAY_DIGIT_1,
+ ON_DAY_DIGIT_2,
+ ON_HOUR_DIGIT_1,
+ ON_HOUR_DIGIT_2,
+ ON_MINUTE_DIGIT_1,
+ ON_MINUTE_DIGIT_2,
+ ON_SECOND_DIGIT_1,
+ ON_SECOND_DIGIT_2,
+ ON_SUBSECOND,
+ ON_TIMEZONE,
+ ON_OFFSET_HOURS_DIGIT_1,
+ ON_OFFSET_HOURS_DIGIT_2,
+ ON_OFFSET_MINUTES_DIGIT_1,
+ ON_OFFSET_MINUTES_DIGIT_2,
+ FINISHED,
+ PARSE_ERROR
+} parser_state;
+
+static inline long get_gmt_offset(struct tm *t) {
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__ANDROID__) || defined(ANDROID) || defined(__APPLE__) && defined(__MACH__)
+ return t->tm_gmtoff;
+#else
+ return t->tm_gmtoff;
+#endif
+}
+
+static inline void get_current_timesettings(long *gmt_offset, int *is_dst) {
+ struct tm time_ptr = {0};
+ time_t raw_time;
+ time(&raw_time);
+ localtime_r(&raw_time, &time_ptr);
+ *gmt_offset = get_gmt_offset(&time_ptr);
+ *is_dst = time_ptr.tm_isdst;
+}
+
+#define PARSE_DIGIT(c, d) do { ENSURE(isdigit(c), S2N_ERR_SAFETY); d = c - '0'; } while(0)
+
+/* this is just a standard state machine for ASN1 date format... nothing special.
+ * just do a character at a time and change the state per character encountered.
+ * when finished the above time structure should be filled in along with some
+ * crazy timezone info we'll need shortly afterwards.*/
+static S2N_RESULT process_state(parser_state *state, char current_char, struct parser_args *args) {
+ switch (*state) {
+ case ON_YEAR_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_year = args->current_digit;
+ *state = ON_YEAR_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_YEAR_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_year = args->time.tm_year * 10 + args->current_digit;
+ *state = ON_YEAR_DIGIT_3;
+ return S2N_RESULT_OK;
+ case ON_YEAR_DIGIT_3:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_year = args->time.tm_year * 10 + args->current_digit;
+ *state = ON_YEAR_DIGIT_4;
+ return S2N_RESULT_OK;
+ case ON_YEAR_DIGIT_4:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_year = args->time.tm_year * 10 + args->current_digit;
+ args->time.tm_year -= 1900;
+ if (args->time.tm_year < 0) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_MONTH_DIGIT_1;
+ return S2N_RESULT_OK;
+ case ON_MONTH_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_mon = args->current_digit;
+ *state = ON_MONTH_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_MONTH_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_mon = args->time.tm_mon * 10 + args->current_digit;
+ args->time.tm_mon -= 1;
+
+ if (args->time.tm_mon < 0 || args->time.tm_mon > 11) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_DAY_DIGIT_1;
+ return S2N_RESULT_OK;
+ case ON_DAY_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_mday = args->current_digit;
+ *state = ON_DAY_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_DAY_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_mday = args->time.tm_mday * 10 + args->current_digit;
+
+ if (args->time.tm_mday < 0 || args->time.tm_mday > 31) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_HOUR_DIGIT_1;
+ return S2N_RESULT_OK;
+ case ON_HOUR_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_hour = args->current_digit;
+ *state = ON_HOUR_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_HOUR_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_hour = args->time.tm_hour * 10 + args->current_digit;
+
+ if (args->time.tm_hour < 0 || args->time.tm_hour > 23) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_MINUTE_DIGIT_1;
+ return S2N_RESULT_OK;
+ case ON_MINUTE_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_min = args->current_digit;
+ *state = ON_MINUTE_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_MINUTE_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_min = args->time.tm_min * 10 + args->current_digit;
+
+ if (args->time.tm_min < 0 || args->time.tm_min > 59) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_SECOND_DIGIT_1;
+ return S2N_RESULT_OK;
+ case ON_SECOND_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_sec = args->current_digit;
+ *state = ON_SECOND_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_SECOND_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->time.tm_sec = args->time.tm_sec * 10 + args->current_digit;
+
+ if (args->time.tm_sec < 0 || args->time.tm_sec > 59) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_SUBSECOND;
+ return S2N_RESULT_OK;
+ case ON_SUBSECOND:
+ if (current_char == '.' || isdigit(current_char)) {
+ *state = ON_SUBSECOND;
+ return S2N_RESULT_OK;
+ }
+ FALL_THROUGH;
+ case ON_TIMEZONE:
+ if (current_char == 'Z' || current_char == 'z') {
+ args->local_time_assumed = 0;
+ *state = FINISHED;
+ return S2N_RESULT_OK;
+ } else if (current_char == '-') {
+ args->local_time_assumed = 0;
+ args->offset_negative = 1;
+ *state = ON_OFFSET_HOURS_DIGIT_1;
+ return S2N_RESULT_OK;
+ } else if (current_char == '+') {
+ args->local_time_assumed = 0;
+ args->offset_negative = 0;
+ *state = ON_OFFSET_HOURS_DIGIT_1;
+ return S2N_RESULT_OK;
+ }
+
+ return S2N_RESULT_ERROR;
+ case ON_OFFSET_HOURS_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->offset_hours = args->current_digit;
+ *state = ON_OFFSET_HOURS_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_OFFSET_HOURS_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->offset_hours = args->offset_hours * 10 + args->current_digit;
+
+ if (args->offset_hours < 0 || args->offset_hours > 23) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = ON_OFFSET_MINUTES_DIGIT_1;
+ return S2N_RESULT_OK;
+ case ON_OFFSET_MINUTES_DIGIT_1:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->offset_minutes = args->current_digit;
+ *state = ON_OFFSET_MINUTES_DIGIT_2;
+ return S2N_RESULT_OK;
+ case ON_OFFSET_MINUTES_DIGIT_2:
+ PARSE_DIGIT(current_char, args->current_digit);
+ args->offset_minutes = args->offset_minutes * 10 + args->current_digit;
+
+ if (args->offset_minutes < 0 || args->offset_minutes > 23) {
+ return S2N_RESULT_ERROR;
+ }
+
+ *state = FINISHED;
+ return S2N_RESULT_OK;
+ default:
+ return S2N_RESULT_ERROR;
+ }
+}
+
+S2N_RESULT s2n_asn1_time_to_nano_since_epoch_ticks(const char *asn1_time, uint32_t len, uint64_t *ticks) {
+
+ /* figure out if we are on something other than UTC since timegm is not supported everywhere. */
+ long gmt_offset_current = 0;
+ int is_dst = 0;
+ get_current_timesettings(&gmt_offset_current, &is_dst);
+
+ uint32_t str_len = len;
+ parser_state state = ON_YEAR_DIGIT_1;
+
+ struct parser_args args = {
+ .time = {.tm_hour = 0, .tm_isdst = -1, .tm_mday = 0, .tm_min = 0, .tm_mon = 0,
+ .tm_sec = 0, .tm_wday = 0, .tm_yday = 0, .tm_year = 0,
+ },
+ .current_digit = 0,
+ .local_time_assumed = 1,
+ .offset_hours = 0,
+ .offset_minutes = 0,
+ .offset_negative = 0
+ };
+
+ size_t current_pos = 0;
+
+ while (state < FINISHED && current_pos < str_len) {
+ char current_char = asn1_time[current_pos];
+ ENSURE_OK(process_state(&state, current_char, &args), S2N_ERR_INVALID_ARGUMENT);
+ current_pos++;
+ }
+
+ /* state on subsecond means no timezone info was found and we assume local time */
+ ENSURE(state == FINISHED || state == ON_SUBSECOND, S2N_ERR_INVALID_ARGUMENT);
+
+ time_t clock_data = mktime(&args.time);
+ ENSURE_GTE(clock_data, 0);
+
+ /* ASN1 + and - is in format HHMM. We need to convert it to seconds for the adjustment */
+ long gmt_offset = (args.offset_hours * 3600) + (args.offset_minutes * 60);
+
+ if (args.offset_negative) {
+ gmt_offset = 0 - gmt_offset;
+ }
+
+ /* if we detected UTC is being used (please always use UTC), we need to add the detected timezone on the local
+ * machine back to the offset. Also, the offset includes an offset for daylight savings time. When the time being parsed
+ * and the local time are on different sides of the dst barrier, the offset has to be adjusted to account for it. */
+ if (!args.local_time_assumed) {
+ gmt_offset -= gmt_offset_current;
+ gmt_offset -= args.time.tm_isdst != is_dst ? (args.time.tm_isdst - is_dst) * 3600 : 0;
+ }
+
+ ENSURE_GTE(clock_data, gmt_offset);
+
+ /* convert to nanoseconds and add the timezone offset. */
+ *ticks = ((uint64_t) clock_data - gmt_offset) * 1000000000;
+ return S2N_RESULT_OK;
+}
+
diff --git a/contrib/restricted/aws/s2n/utils/s2n_asn1_time.h b/contrib/restricted/aws/s2n/utils/s2n_asn1_time.h
index e7f88a81b4..73318b28b1 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_asn1_time.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_asn1_time.h
@@ -1,37 +1,37 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <time.h>
-
-#include "utils/s2n_result.h"
-
-struct parser_args {
- uint8_t offset_negative;
- uint8_t local_time_assumed;
- uint8_t current_digit;
- long offset_hours;
- long offset_minutes;
- struct tm time;
-};
-
-/**
- * Converts an asn1 formatted time string to ticks since epoch in nanoseconds.
- * ticks is an output parameter. Returns 0 on success and -1 on failure.
- */
-S2N_RESULT s2n_asn1_time_to_nano_since_epoch_ticks(const char *asn1_time, uint32_t len, uint64_t *ticks);
-
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <time.h>
+
+#include "utils/s2n_result.h"
+
+struct parser_args {
+ uint8_t offset_negative;
+ uint8_t local_time_assumed;
+ uint8_t current_digit;
+ long offset_hours;
+ long offset_minutes;
+ struct tm time;
+};
+
+/**
+ * Converts an asn1 formatted time string to ticks since epoch in nanoseconds.
+ * ticks is an output parameter. Returns 0 on success and -1 on failure.
+ */
+S2N_RESULT s2n_asn1_time_to_nano_since_epoch_ticks(const char *asn1_time, uint32_t len, uint64_t *ticks);
+
diff --git a/contrib/restricted/aws/s2n/utils/s2n_bitmap.h b/contrib/restricted/aws/s2n/utils/s2n_bitmap.h
index f13a7fd911..9ee892fc14 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_bitmap.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_bitmap.h
@@ -1,22 +1,22 @@
-/*
- * 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.
- */
-#pragma once
-
-/* bit operations on a char[] mask of arbitrary length */
-#define S2N_CBIT_BIT(bit) (1 << ((bit) % 8))
-#define S2N_CBIT_BIN(mask, bit) (mask)[(bit) >> 3]
-#define S2N_CBIT_SET(mask, bit) ((void)(S2N_CBIT_BIN(mask, bit) |= S2N_CBIT_BIT(bit)))
-#define S2N_CBIT_CLR(mask, bit) ((void)(S2N_CBIT_BIN(mask, bit) &= ~S2N_CBIT_BIT(bit)))
-#define S2N_CBIT_TEST(mask, bit) ((S2N_CBIT_BIN(mask, bit) & S2N_CBIT_BIT(bit)) != 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.
+ */
+#pragma once
+
+/* bit operations on a char[] mask of arbitrary length */
+#define S2N_CBIT_BIT(bit) (1 << ((bit) % 8))
+#define S2N_CBIT_BIN(mask, bit) (mask)[(bit) >> 3]
+#define S2N_CBIT_SET(mask, bit) ((void)(S2N_CBIT_BIN(mask, bit) |= S2N_CBIT_BIT(bit)))
+#define S2N_CBIT_CLR(mask, bit) ((void)(S2N_CBIT_BIN(mask, bit) &= ~S2N_CBIT_BIT(bit)))
+#define S2N_CBIT_TEST(mask, bit) ((S2N_CBIT_BIN(mask, bit) & S2N_CBIT_BIT(bit)) != 0)
diff --git a/contrib/restricted/aws/s2n/utils/s2n_blob.c b/contrib/restricted/aws/s2n/utils/s2n_blob.c
index 649fb55c0d..0704f730a3 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_blob.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_blob.c
@@ -1,126 +1,126 @@
-/*
- * 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 <string.h>
-#include <ctype.h>
-#include <sys/param.h>
-
-#include "error/s2n_errno.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-#include <s2n.h>
-
-S2N_RESULT s2n_blob_validate(const struct s2n_blob* b)
-{
- ENSURE_REF(b);
- DEBUG_ENSURE(S2N_IMPLIES(b->data == NULL, b->size == 0), S2N_ERR_SAFETY);
- DEBUG_ENSURE(S2N_IMPLIES(b->data == NULL, b->allocated == 0), S2N_ERR_SAFETY);
- DEBUG_ENSURE(S2N_IMPLIES(b->growable == 0, b->allocated == 0), S2N_ERR_SAFETY);
- DEBUG_ENSURE(S2N_IMPLIES(b->growable != 0, b->size <= b->allocated), S2N_ERR_SAFETY);
- DEBUG_ENSURE(S2N_MEM_IS_READABLE(b->data, b->allocated), S2N_ERR_SAFETY);
- DEBUG_ENSURE(S2N_MEM_IS_READABLE(b->data, b->size), S2N_ERR_SAFETY);
- return S2N_RESULT_OK;
-}
-
-int s2n_blob_init(struct s2n_blob *b, uint8_t * data, uint32_t size)
-{
- ENSURE_POSIX_REF(b);
- ENSURE_POSIX(S2N_MEM_IS_READABLE(data, size), S2N_ERR_SAFETY);
- *b = (struct s2n_blob) {.data = data, .size = size, .allocated = 0, .growable = 0};
- POSTCONDITION_POSIX(s2n_blob_validate(b));
- return S2N_SUCCESS;
-}
-
-int s2n_blob_zero(struct s2n_blob *b)
-{
- PRECONDITION_POSIX(s2n_blob_validate(b));
- memset_check(b->data, 0, MAX(b->allocated, b->size));
- POSTCONDITION_POSIX(s2n_blob_validate(b));
- return S2N_SUCCESS;
-}
-
-int s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob *slice, uint32_t offset, uint32_t size)
-{
- PRECONDITION_POSIX(s2n_blob_validate(b));
- PRECONDITION_POSIX(s2n_blob_validate(slice));
-
- uint32_t slice_size = 0;
- GUARD(s2n_add_overflow(offset, size, &slice_size));
- ENSURE_POSIX(b->size >= slice_size, S2N_ERR_SIZE_MISMATCH);
- slice->data = b->data + offset;
- slice->size = size;
- slice->growable = 0;
- slice->allocated = 0;
-
- POSTCONDITION_POSIX(s2n_blob_validate(slice));
- return S2N_SUCCESS;
-}
-
-int s2n_blob_char_to_lower(struct s2n_blob *b)
-{
- PRECONDITION_POSIX(s2n_blob_validate(b));
- for (size_t i = 0; i < b->size; i++) {
- b->data[i] = tolower(b->data[i]);
- }
- POSTCONDITION_POSIX(s2n_blob_validate(b));
- return S2N_SUCCESS;
-}
-
-/* An inverse map from an ascii value to a hexidecimal nibble value
- * accounts for all possible char values, where 255 is invalid value */
-static const uint8_t hex_inverse[256] = {
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
- 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
-};
-
-/* takes a hex string and writes values in the s2n_blob
- * string needs to a valid hex and blob needs to be large enough */
-int s2n_hex_string_to_bytes(const uint8_t *str, struct s2n_blob *blob)
-{
- ENSURE_POSIX_REF(str);
- PRECONDITION_POSIX(s2n_blob_validate(blob));
- uint32_t len = strlen((const char*)str);
- /* protects against overflows */
- gte_check(blob->size, len / 2);
- S2N_ERROR_IF(len % 2 != 0, S2N_ERR_INVALID_HEX);
-
- for (size_t i = 0; i < len; i += 2) {
- uint8_t high_nibble = hex_inverse[str[i]];
- S2N_ERROR_IF(high_nibble == 255, S2N_ERR_INVALID_HEX);
-
- uint8_t low_nibble = hex_inverse[str[i + 1]];
- S2N_ERROR_IF(low_nibble == 255, S2N_ERR_INVALID_HEX);
- blob->data[i / 2] = high_nibble << 4 | low_nibble;
- }
-
- POSTCONDITION_POSIX(s2n_blob_validate(blob));
- return S2N_SUCCESS;
-}
+/*
+ * 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 <string.h>
+#include <ctype.h>
+#include <sys/param.h>
+
+#include "error/s2n_errno.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+#include <s2n.h>
+
+S2N_RESULT s2n_blob_validate(const struct s2n_blob* b)
+{
+ ENSURE_REF(b);
+ DEBUG_ENSURE(S2N_IMPLIES(b->data == NULL, b->size == 0), S2N_ERR_SAFETY);
+ DEBUG_ENSURE(S2N_IMPLIES(b->data == NULL, b->allocated == 0), S2N_ERR_SAFETY);
+ DEBUG_ENSURE(S2N_IMPLIES(b->growable == 0, b->allocated == 0), S2N_ERR_SAFETY);
+ DEBUG_ENSURE(S2N_IMPLIES(b->growable != 0, b->size <= b->allocated), S2N_ERR_SAFETY);
+ DEBUG_ENSURE(S2N_MEM_IS_READABLE(b->data, b->allocated), S2N_ERR_SAFETY);
+ DEBUG_ENSURE(S2N_MEM_IS_READABLE(b->data, b->size), S2N_ERR_SAFETY);
+ return S2N_RESULT_OK;
+}
+
+int s2n_blob_init(struct s2n_blob *b, uint8_t * data, uint32_t size)
+{
+ ENSURE_POSIX_REF(b);
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(data, size), S2N_ERR_SAFETY);
+ *b = (struct s2n_blob) {.data = data, .size = size, .allocated = 0, .growable = 0};
+ POSTCONDITION_POSIX(s2n_blob_validate(b));
+ return S2N_SUCCESS;
+}
+
+int s2n_blob_zero(struct s2n_blob *b)
+{
+ PRECONDITION_POSIX(s2n_blob_validate(b));
+ memset_check(b->data, 0, MAX(b->allocated, b->size));
+ POSTCONDITION_POSIX(s2n_blob_validate(b));
+ return S2N_SUCCESS;
+}
+
+int s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob *slice, uint32_t offset, uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_blob_validate(b));
+ PRECONDITION_POSIX(s2n_blob_validate(slice));
+
+ uint32_t slice_size = 0;
+ GUARD(s2n_add_overflow(offset, size, &slice_size));
+ ENSURE_POSIX(b->size >= slice_size, S2N_ERR_SIZE_MISMATCH);
+ slice->data = b->data + offset;
+ slice->size = size;
+ slice->growable = 0;
+ slice->allocated = 0;
+
+ POSTCONDITION_POSIX(s2n_blob_validate(slice));
+ return S2N_SUCCESS;
+}
+
+int s2n_blob_char_to_lower(struct s2n_blob *b)
+{
+ PRECONDITION_POSIX(s2n_blob_validate(b));
+ for (size_t i = 0; i < b->size; i++) {
+ b->data[i] = tolower(b->data[i]);
+ }
+ POSTCONDITION_POSIX(s2n_blob_validate(b));
+ return S2N_SUCCESS;
+}
+
+/* An inverse map from an ascii value to a hexidecimal nibble value
+ * accounts for all possible char values, where 255 is invalid value */
+static const uint8_t hex_inverse[256] = {
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+ 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+};
+
+/* takes a hex string and writes values in the s2n_blob
+ * string needs to a valid hex and blob needs to be large enough */
+int s2n_hex_string_to_bytes(const uint8_t *str, struct s2n_blob *blob)
+{
+ ENSURE_POSIX_REF(str);
+ PRECONDITION_POSIX(s2n_blob_validate(blob));
+ uint32_t len = strlen((const char*)str);
+ /* protects against overflows */
+ gte_check(blob->size, len / 2);
+ S2N_ERROR_IF(len % 2 != 0, S2N_ERR_INVALID_HEX);
+
+ for (size_t i = 0; i < len; i += 2) {
+ uint8_t high_nibble = hex_inverse[str[i]];
+ S2N_ERROR_IF(high_nibble == 255, S2N_ERR_INVALID_HEX);
+
+ uint8_t low_nibble = hex_inverse[str[i + 1]];
+ S2N_ERROR_IF(low_nibble == 255, S2N_ERR_INVALID_HEX);
+ blob->data[i / 2] = high_nibble << 4 | low_nibble;
+ }
+
+ POSTCONDITION_POSIX(s2n_blob_validate(blob));
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_blob.h b/contrib/restricted/aws/s2n/utils/s2n_blob.h
index 8391b3567f..5361ff2f32 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_blob.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_blob.h
@@ -1,67 +1,67 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include "utils/s2n_result.h"
-
-struct s2n_blob {
- /* The data for the s2n_blob */
- uint8_t *data;
-
- /* The size of the data */
- uint32_t size;
-
- /* The amount of memory allocated for this blob (i.e. the amount of memory
- * which needs to be freed when the blob is cleaned up). If this blob was
- * created with s2n_blob_init(), this value is 0. If s2n_alloc() was called,
- * this value will be greater than 0.
- */
- uint32_t allocated;
-
- /* Can this blob be resized */
- unsigned growable :1;
-};
-
-
-extern bool s2n_blob_is_growable(const struct s2n_blob* b);
-extern S2N_RESULT s2n_blob_validate(const struct s2n_blob* b);
-extern int s2n_blob_init(struct s2n_blob *b, uint8_t * data, uint32_t size);
-extern int s2n_blob_zero(struct s2n_blob *b);
-extern int s2n_blob_char_to_lower(struct s2n_blob *b);
-extern int s2n_hex_string_to_bytes(const uint8_t *str, struct s2n_blob *blob);
-extern int s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob *slice, uint32_t offset, uint32_t size);
-
-#define s2n_stack_blob(name, requested_size, maximum) \
- size_t name ## _requested_size = (requested_size); \
- uint8_t name ## _buf[(maximum)] = {0}; \
- lte_check(name ## _requested_size, (maximum)); \
- struct s2n_blob name = {0}; \
- GUARD(s2n_blob_init(&name, name ## _buf, name ## _requested_size))
-
-#define S2N_BLOB_LABEL(name, str) \
- static uint8_t name##_data[] = str; \
- const struct s2n_blob name = { .data = name##_data, .size = sizeof(name##_data) - 1 };
-
-/* The S2N_BLOB_FROM_HEX macro creates a s2n_blob with the contents of a hex string.
- * It is allocated on a stack so there no need to free after use.
- * hex should be a const char[]. This function checks against using char*,
- * because sizeof needs to refer to the buffer length rather than a pointer size */
-#define S2N_BLOB_FROM_HEX( name, hex ) \
- s2n_stack_blob(name, (sizeof(hex) - 1) / 2, (sizeof(hex) - 1) / 2); \
- GUARD(s2n_hex_string_to_bytes((const uint8_t*)hex, &name));
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "utils/s2n_result.h"
+
+struct s2n_blob {
+ /* The data for the s2n_blob */
+ uint8_t *data;
+
+ /* The size of the data */
+ uint32_t size;
+
+ /* The amount of memory allocated for this blob (i.e. the amount of memory
+ * which needs to be freed when the blob is cleaned up). If this blob was
+ * created with s2n_blob_init(), this value is 0. If s2n_alloc() was called,
+ * this value will be greater than 0.
+ */
+ uint32_t allocated;
+
+ /* Can this blob be resized */
+ unsigned growable :1;
+};
+
+
+extern bool s2n_blob_is_growable(const struct s2n_blob* b);
+extern S2N_RESULT s2n_blob_validate(const struct s2n_blob* b);
+extern int s2n_blob_init(struct s2n_blob *b, uint8_t * data, uint32_t size);
+extern int s2n_blob_zero(struct s2n_blob *b);
+extern int s2n_blob_char_to_lower(struct s2n_blob *b);
+extern int s2n_hex_string_to_bytes(const uint8_t *str, struct s2n_blob *blob);
+extern int s2n_blob_slice(const struct s2n_blob *b, struct s2n_blob *slice, uint32_t offset, uint32_t size);
+
+#define s2n_stack_blob(name, requested_size, maximum) \
+ size_t name ## _requested_size = (requested_size); \
+ uint8_t name ## _buf[(maximum)] = {0}; \
+ lte_check(name ## _requested_size, (maximum)); \
+ struct s2n_blob name = {0}; \
+ GUARD(s2n_blob_init(&name, name ## _buf, name ## _requested_size))
+
+#define S2N_BLOB_LABEL(name, str) \
+ static uint8_t name##_data[] = str; \
+ const struct s2n_blob name = { .data = name##_data, .size = sizeof(name##_data) - 1 };
+
+/* The S2N_BLOB_FROM_HEX macro creates a s2n_blob with the contents of a hex string.
+ * It is allocated on a stack so there no need to free after use.
+ * hex should be a const char[]. This function checks against using char*,
+ * because sizeof needs to refer to the buffer length rather than a pointer size */
+#define S2N_BLOB_FROM_HEX( name, hex ) \
+ s2n_stack_blob(name, (sizeof(hex) - 1) / 2, (sizeof(hex) - 1) / 2); \
+ GUARD(s2n_hex_string_to_bytes((const uint8_t*)hex, &name));
diff --git a/contrib/restricted/aws/s2n/utils/s2n_compiler.h b/contrib/restricted/aws/s2n/utils/s2n_compiler.h
index 989fe266f2..4b91d0bbfc 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_compiler.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_compiler.h
@@ -1,24 +1,24 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#define S2N_GCC_VERSION (__GNUC__ * 10000 \
- + __GNUC_MINOR__ * 100 \
- + __GNUC_PATCHLEVEL__)
-
-#define S2N_GCC_VERSION_AT_LEAST(major, minor, patch_level) \
- ((S2N_GCC_VERSION) >= ((major) * 10000 + (minor) * 100 + (patch_level)))
-
+/*
+ * 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.
+ */
+
+#pragma once
+
+#define S2N_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
+#define S2N_GCC_VERSION_AT_LEAST(major, minor, patch_level) \
+ ((S2N_GCC_VERSION) >= ((major) * 10000 + (minor) * 100 + (patch_level)))
+
diff --git a/contrib/restricted/aws/s2n/utils/s2n_ensure.c b/contrib/restricted/aws/s2n/utils/s2n_ensure.c
index 4cfe7e40c9..aa0b181c2b 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_ensure.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_ensure.c
@@ -1,27 +1,27 @@
-/*
- * 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 "utils/s2n_safety.h"
-
-void* s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size, const char *debug_str)
-{
- if (to == NULL || from == NULL) {
- s2n_errno = S2N_ERR_NULL;
- s2n_debug_str = debug_str;
- return NULL;
- }
-
- return memcpy(to, from, size);
-}
+/*
+ * 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 "utils/s2n_safety.h"
+
+void* s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size, const char *debug_str)
+{
+ if (to == NULL || from == NULL) {
+ s2n_errno = S2N_ERR_NULL;
+ s2n_debug_str = debug_str;
+ return NULL;
+ }
+
+ return memcpy(to, from, size);
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_ensure.h b/contrib/restricted/aws/s2n/utils/s2n_ensure.h
index 8949521e9a..a3e2286192 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_ensure.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_ensure.h
@@ -1,70 +1,70 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#define s2n_likely(x) __builtin_expect(!!(x), 1)
-#define s2n_unlikely(x) __builtin_expect(!!(x), 0)
-
-/**
- * s2n_ensure provides low-level safety check functionality
- *
- * This should only consumed directly by s2n_safety.
- *
- * Note: This module can be replaced by static analyzer implementation
- * to insert additional safety checks.
- */
-
-/**
- * Ensures `cond` is true, otherwise `action` will be performed
- */
-#define __S2N_ENSURE( cond, action ) do {if ( !(cond) ) { action; }} while (0)
-
-#define __S2N_ENSURE_LIKELY( cond, action ) do {if ( s2n_unlikely( !(cond) ) ) { action; }} while (0)
-
-#ifdef NDEBUG
-#define __S2N_ENSURE_DEBUG( cond, action ) do {} while (0)
-#else
-#define __S2N_ENSURE_DEBUG( cond, action ) __S2N_ENSURE_LIKELY((cond), action)
-#endif
-
-#define __S2N_ENSURE_PRECONDITION( result ) (s2n_likely(s2n_result_is_ok(result)) ? S2N_RESULT_OK : S2N_RESULT_ERROR)
-
-#ifdef NDEBUG
-#define __S2N_ENSURE_POSTCONDITION( result ) (S2N_RESULT_OK)
-#else
-#define __S2N_ENSURE_POSTCONDITION( result ) (s2n_likely(s2n_result_is_ok(result)) ? S2N_RESULT_OK : S2N_RESULT_ERROR)
-#endif
-
-#define __S2N_ENSURE_SAFE_MEMCPY( d , s , n , guard ) \
- do { \
- __typeof( n ) __tmp_n = ( n ); \
- if ( s2n_likely( __tmp_n ) ) { \
- void *r = s2n_ensure_memcpy_trace( (d), (s) , (__tmp_n), _S2N_DEBUG_LINE); \
- guard(r); \
- } \
- } while(0)
-
-#define __S2N_ENSURE_SAFE_MEMSET( d , c , n , guard ) \
- do { \
- __typeof( n ) __tmp_n = ( n ); \
- if ( s2n_likely( __tmp_n ) ) { \
- __typeof( d ) __tmp_d = ( d ); \
- guard( __tmp_d ); \
- memset( __tmp_d, (c), __tmp_n); \
- } \
- } while(0)
-
-extern void* s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size, const char *debug_str);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#define s2n_likely(x) __builtin_expect(!!(x), 1)
+#define s2n_unlikely(x) __builtin_expect(!!(x), 0)
+
+/**
+ * s2n_ensure provides low-level safety check functionality
+ *
+ * This should only consumed directly by s2n_safety.
+ *
+ * Note: This module can be replaced by static analyzer implementation
+ * to insert additional safety checks.
+ */
+
+/**
+ * Ensures `cond` is true, otherwise `action` will be performed
+ */
+#define __S2N_ENSURE( cond, action ) do {if ( !(cond) ) { action; }} while (0)
+
+#define __S2N_ENSURE_LIKELY( cond, action ) do {if ( s2n_unlikely( !(cond) ) ) { action; }} while (0)
+
+#ifdef NDEBUG
+#define __S2N_ENSURE_DEBUG( cond, action ) do {} while (0)
+#else
+#define __S2N_ENSURE_DEBUG( cond, action ) __S2N_ENSURE_LIKELY((cond), action)
+#endif
+
+#define __S2N_ENSURE_PRECONDITION( result ) (s2n_likely(s2n_result_is_ok(result)) ? S2N_RESULT_OK : S2N_RESULT_ERROR)
+
+#ifdef NDEBUG
+#define __S2N_ENSURE_POSTCONDITION( result ) (S2N_RESULT_OK)
+#else
+#define __S2N_ENSURE_POSTCONDITION( result ) (s2n_likely(s2n_result_is_ok(result)) ? S2N_RESULT_OK : S2N_RESULT_ERROR)
+#endif
+
+#define __S2N_ENSURE_SAFE_MEMCPY( d , s , n , guard ) \
+ do { \
+ __typeof( n ) __tmp_n = ( n ); \
+ if ( s2n_likely( __tmp_n ) ) { \
+ void *r = s2n_ensure_memcpy_trace( (d), (s) , (__tmp_n), _S2N_DEBUG_LINE); \
+ guard(r); \
+ } \
+ } while(0)
+
+#define __S2N_ENSURE_SAFE_MEMSET( d , c , n , guard ) \
+ do { \
+ __typeof( n ) __tmp_n = ( n ); \
+ if ( s2n_likely( __tmp_n ) ) { \
+ __typeof( d ) __tmp_d = ( d ); \
+ guard( __tmp_d ); \
+ memset( __tmp_d, (c), __tmp_n); \
+ } \
+ } while(0)
+
+extern void* s2n_ensure_memcpy_trace(void *restrict to, const void *restrict from, size_t size, const char *debug_str);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_init.c b/contrib/restricted/aws/s2n/utils/s2n_init.c
index 0f79f959fb..2e3757742a 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_init.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_init.c
@@ -1,83 +1,83 @@
-/*
- * 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 "crypto/s2n_fips.h"
-
-#include "error/s2n_errno.h"
-
-#include "tls/s2n_cipher_suites.h"
-#include "tls/extensions/s2n_extension_type.h"
-#include "tls/s2n_security_policies.h"
-#include "tls/extensions/s2n_client_key_share.h"
-
-#include "utils/s2n_mem.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_safety.h"
-
-#include "openssl/opensslv.h"
-
-#include "pq-crypto/s2n_pq.h"
-
-static void s2n_cleanup_atexit(void);
-
-unsigned long s2n_get_openssl_version(void)
-{
- return OPENSSL_VERSION_NUMBER;
-}
-
-int s2n_init(void)
-{
- GUARD_POSIX(s2n_fips_init());
- GUARD_POSIX(s2n_mem_init());
- GUARD_AS_POSIX(s2n_rand_init());
- GUARD_POSIX(s2n_cipher_suites_init());
- GUARD_POSIX(s2n_security_policies_init());
- GUARD_POSIX(s2n_config_defaults_init());
- GUARD_POSIX(s2n_extension_type_init());
- GUARD_AS_POSIX(s2n_pq_init());
-
- S2N_ERROR_IF(atexit(s2n_cleanup_atexit) != 0, S2N_ERR_ATEXIT);
-
- if (getenv("S2N_PRINT_STACKTRACE")) {
- s2n_stack_traces_enabled_set(true);
- }
-
- return 0;
-}
-
-int s2n_cleanup(void)
-{
- /* s2n_cleanup is supposed to be called from each thread before exiting,
- * so ensure that whatever clean ups we have here are thread safe */
- GUARD_AS_POSIX(s2n_rand_cleanup_thread());
- return 0;
-}
-
-static bool s2n_cleanup_atexit_impl(void)
-{
- /* all of these should run, regardless of result, but the
- * values to need to be consumed to prevent warnings */
- bool a = s2n_result_is_ok(s2n_rand_cleanup_thread());
- bool b = s2n_result_is_ok(s2n_rand_cleanup());
- bool c = s2n_mem_cleanup() == 0;
- s2n_wipe_static_configs();
-
- return a && b && c;
-}
-
-static void s2n_cleanup_atexit(void)
-{
- s2n_cleanup_atexit_impl();
-}
-
+/*
+ * 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 "crypto/s2n_fips.h"
+
+#include "error/s2n_errno.h"
+
+#include "tls/s2n_cipher_suites.h"
+#include "tls/extensions/s2n_extension_type.h"
+#include "tls/s2n_security_policies.h"
+#include "tls/extensions/s2n_client_key_share.h"
+
+#include "utils/s2n_mem.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_safety.h"
+
+#include "openssl/opensslv.h"
+
+#include "pq-crypto/s2n_pq.h"
+
+static void s2n_cleanup_atexit(void);
+
+unsigned long s2n_get_openssl_version(void)
+{
+ return OPENSSL_VERSION_NUMBER;
+}
+
+int s2n_init(void)
+{
+ GUARD_POSIX(s2n_fips_init());
+ GUARD_POSIX(s2n_mem_init());
+ GUARD_AS_POSIX(s2n_rand_init());
+ GUARD_POSIX(s2n_cipher_suites_init());
+ GUARD_POSIX(s2n_security_policies_init());
+ GUARD_POSIX(s2n_config_defaults_init());
+ GUARD_POSIX(s2n_extension_type_init());
+ GUARD_AS_POSIX(s2n_pq_init());
+
+ S2N_ERROR_IF(atexit(s2n_cleanup_atexit) != 0, S2N_ERR_ATEXIT);
+
+ if (getenv("S2N_PRINT_STACKTRACE")) {
+ s2n_stack_traces_enabled_set(true);
+ }
+
+ return 0;
+}
+
+int s2n_cleanup(void)
+{
+ /* s2n_cleanup is supposed to be called from each thread before exiting,
+ * so ensure that whatever clean ups we have here are thread safe */
+ GUARD_AS_POSIX(s2n_rand_cleanup_thread());
+ return 0;
+}
+
+static bool s2n_cleanup_atexit_impl(void)
+{
+ /* all of these should run, regardless of result, but the
+ * values to need to be consumed to prevent warnings */
+ bool a = s2n_result_is_ok(s2n_rand_cleanup_thread());
+ bool b = s2n_result_is_ok(s2n_rand_cleanup());
+ bool c = s2n_mem_cleanup() == 0;
+ s2n_wipe_static_configs();
+
+ return a && b && c;
+}
+
+static void s2n_cleanup_atexit(void)
+{
+ s2n_cleanup_atexit_impl();
+}
+
diff --git a/contrib/restricted/aws/s2n/utils/s2n_map.c b/contrib/restricted/aws/s2n/utils/s2n_map.c
index 8851b14e1b..3477a93bb7 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_map.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_map.c
@@ -1,240 +1,240 @@
-/*
- * 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 <string.h>
-#include <stdio.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_hash.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_result.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_map.h"
-#include "utils/s2n_map_internal.h"
-
-#include <s2n.h>
-
-#define S2N_INITIAL_TABLE_SIZE 1024
-
-static S2N_RESULT s2n_map_slot(const struct s2n_map *map, struct s2n_blob *key, uint32_t *slot)
-{
- union {
- uint8_t u8[32];
- uint32_t u32[8];
- } digest;
-
- DEFER_CLEANUP(struct s2n_hash_state sha256 = {0}, s2n_hash_free);
- GUARD_AS_RESULT(s2n_hash_new(&sha256));
- GUARD_AS_RESULT(s2n_hash_init(&sha256, S2N_HASH_SHA256));
- GUARD_AS_RESULT(s2n_hash_update(&sha256, key->data, key->size));
- GUARD_AS_RESULT(s2n_hash_digest(&sha256, digest.u8, sizeof(digest)));
-
- *slot = digest.u32[0] % map->capacity;
- return S2N_RESULT_OK;
-}
-
-static S2N_RESULT s2n_map_embiggen(struct s2n_map *map, uint32_t capacity)
-{
- struct s2n_blob mem = {0};
- struct s2n_map tmp = {0};
-
- ENSURE(!map->immutable, S2N_ERR_MAP_IMMUTABLE);
-
- GUARD_AS_RESULT(s2n_alloc(&mem, (capacity * sizeof(struct s2n_map_entry))));
- GUARD_AS_RESULT(s2n_blob_zero(&mem));
-
- tmp.capacity = capacity;
- tmp.size = 0;
- tmp.table = (void *) mem.data;
- tmp.immutable = 0;
-
- for (int i = 0; i < map->capacity; i++) {
- if (map->table[i].key.size) {
- GUARD_RESULT(s2n_map_add(&tmp, &map->table[i].key, &map->table[i].value));
- GUARD_AS_RESULT(s2n_free(&map->table[i].key));
- GUARD_AS_RESULT(s2n_free(&map->table[i].value));
- }
- }
- GUARD_AS_RESULT(s2n_free_object((uint8_t **)&map->table, map->capacity * sizeof(struct s2n_map_entry)));
-
- /* Clone the temporary map */
- map->capacity = tmp.capacity;
- map->size = tmp.size;
- map->table = tmp.table;
- map->immutable = 0;
-
- return S2N_RESULT_OK;
-}
-
-struct s2n_map *s2n_map_new()
-{
- return s2n_map_new_with_initial_capacity(S2N_INITIAL_TABLE_SIZE);
-}
-
-struct s2n_map *s2n_map_new_with_initial_capacity(uint32_t capacity)
-{
- S2N_ERROR_IF_PTR(capacity == 0, S2N_ERR_MAP_INVALID_MAP_SIZE);
- struct s2n_blob mem = {0};
- struct s2n_map *map;
-
- GUARD_POSIX_PTR(s2n_alloc(&mem, sizeof(struct s2n_map)));
-
- map = (void *) mem.data;
- map->capacity = 0;
- map->size = 0;
- map->immutable = 0;
- map->table = NULL;
-
- GUARD_RESULT_PTR(s2n_map_embiggen(map, capacity));
-
- return map;
-}
-
-S2N_RESULT s2n_map_add(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value)
-{
- ENSURE(!map->immutable, S2N_ERR_MAP_IMMUTABLE);
-
- if (map->capacity < (map->size * 2)) {
- /* Embiggen the map */
- GUARD_RESULT(s2n_map_embiggen(map, map->capacity * 2));
- }
-
- uint32_t slot = 0;
- GUARD_RESULT(s2n_map_slot(map, key, &slot));
-
- /* Linear probing until we find an empty slot */
- while(map->table[slot].key.size) {
- if (key->size != map->table[slot].key.size ||
- memcmp(key->data, map->table[slot].key.data, key->size)) {
- slot++;
- slot %= map->capacity;
- continue;
- }
-
- /* We found a duplicate key */
- BAIL(S2N_ERR_MAP_DUPLICATE);
- }
-
- GUARD_AS_RESULT(s2n_dup(key, &map->table[slot].key));
- GUARD_AS_RESULT(s2n_dup(value, &map->table[slot].value));
- map->size++;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_map_put(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value)
-{
- ENSURE(!map->immutable, S2N_ERR_MAP_IMMUTABLE);
-
- if (map->capacity < (map->size * 2)) {
- /* Embiggen the map */
- GUARD_RESULT(s2n_map_embiggen(map, map->capacity * 2));
- }
-
- uint32_t slot = 0;
- GUARD_RESULT(s2n_map_slot(map, key, &slot));
-
- /* Linear probing until we find an empty slot */
- while(map->table[slot].key.size) {
- if (key->size != map->table[slot].key.size ||
- memcmp(key->data, map->table[slot].key.data, key->size)) {
- slot++;
- slot %= map->capacity;
- continue;
- }
-
- /* We found a duplicate key that will be overwritten */
- GUARD_AS_RESULT(s2n_free(&map->table[slot].key));
- GUARD_AS_RESULT(s2n_free(&map->table[slot].value));
- map->size--;
- break;
- }
-
- GUARD_AS_RESULT(s2n_dup(key, &map->table[slot].key));
- GUARD_AS_RESULT(s2n_dup(value, &map->table[slot].value));
- map->size++;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_map_complete(struct s2n_map *map)
-{
- map->immutable = 1;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_map_unlock(struct s2n_map *map)
-{
- map->immutable = 0;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_map_lookup(const struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value, bool *key_found)
-{
- ENSURE(map->immutable, S2N_ERR_MAP_MUTABLE);
-
- uint32_t slot = 0;
- GUARD_RESULT(s2n_map_slot(map, key, &slot));
- const uint32_t initial_slot = slot;
-
- while(map->table[slot].key.size) {
- if (key->size != map->table[slot].key.size ||
- memcmp(key->data, map->table[slot].key.data, key->size)) {
- slot++;
- slot %= map->capacity;
- /* We went over all the slots but found no match */
- if (slot == initial_slot) {
- break;
- }
- continue;
- }
-
- /* We found a match */
- value->data = map->table[slot].value.data;
- value->size = map->table[slot].value.size;
-
- *key_found = true;
-
- return S2N_RESULT_OK;
- }
-
- *key_found = false;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_map_free(struct s2n_map *map)
-{
- /* Free the keys and values */
- for (int i = 0; i < map->capacity; i++) {
- if (map->table[i].key.size) {
- GUARD_AS_RESULT(s2n_free(&map->table[i].key));
- GUARD_AS_RESULT(s2n_free(&map->table[i].value));
- }
- }
-
- /* Free the table */
- GUARD_AS_RESULT(s2n_free_object((uint8_t **)&map->table, map->capacity * sizeof(struct s2n_map_entry)));
-
- /* And finally the map */
- GUARD_AS_RESULT(s2n_free_object((uint8_t **)&map, sizeof(struct s2n_map)));
-
- return S2N_RESULT_OK;
-}
+/*
+ * 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 <string.h>
+#include <stdio.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_hash.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_result.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_map.h"
+#include "utils/s2n_map_internal.h"
+
+#include <s2n.h>
+
+#define S2N_INITIAL_TABLE_SIZE 1024
+
+static S2N_RESULT s2n_map_slot(const struct s2n_map *map, struct s2n_blob *key, uint32_t *slot)
+{
+ union {
+ uint8_t u8[32];
+ uint32_t u32[8];
+ } digest;
+
+ DEFER_CLEANUP(struct s2n_hash_state sha256 = {0}, s2n_hash_free);
+ GUARD_AS_RESULT(s2n_hash_new(&sha256));
+ GUARD_AS_RESULT(s2n_hash_init(&sha256, S2N_HASH_SHA256));
+ GUARD_AS_RESULT(s2n_hash_update(&sha256, key->data, key->size));
+ GUARD_AS_RESULT(s2n_hash_digest(&sha256, digest.u8, sizeof(digest)));
+
+ *slot = digest.u32[0] % map->capacity;
+ return S2N_RESULT_OK;
+}
+
+static S2N_RESULT s2n_map_embiggen(struct s2n_map *map, uint32_t capacity)
+{
+ struct s2n_blob mem = {0};
+ struct s2n_map tmp = {0};
+
+ ENSURE(!map->immutable, S2N_ERR_MAP_IMMUTABLE);
+
+ GUARD_AS_RESULT(s2n_alloc(&mem, (capacity * sizeof(struct s2n_map_entry))));
+ GUARD_AS_RESULT(s2n_blob_zero(&mem));
+
+ tmp.capacity = capacity;
+ tmp.size = 0;
+ tmp.table = (void *) mem.data;
+ tmp.immutable = 0;
+
+ for (int i = 0; i < map->capacity; i++) {
+ if (map->table[i].key.size) {
+ GUARD_RESULT(s2n_map_add(&tmp, &map->table[i].key, &map->table[i].value));
+ GUARD_AS_RESULT(s2n_free(&map->table[i].key));
+ GUARD_AS_RESULT(s2n_free(&map->table[i].value));
+ }
+ }
+ GUARD_AS_RESULT(s2n_free_object((uint8_t **)&map->table, map->capacity * sizeof(struct s2n_map_entry)));
+
+ /* Clone the temporary map */
+ map->capacity = tmp.capacity;
+ map->size = tmp.size;
+ map->table = tmp.table;
+ map->immutable = 0;
+
+ return S2N_RESULT_OK;
+}
+
+struct s2n_map *s2n_map_new()
+{
+ return s2n_map_new_with_initial_capacity(S2N_INITIAL_TABLE_SIZE);
+}
+
+struct s2n_map *s2n_map_new_with_initial_capacity(uint32_t capacity)
+{
+ S2N_ERROR_IF_PTR(capacity == 0, S2N_ERR_MAP_INVALID_MAP_SIZE);
+ struct s2n_blob mem = {0};
+ struct s2n_map *map;
+
+ GUARD_POSIX_PTR(s2n_alloc(&mem, sizeof(struct s2n_map)));
+
+ map = (void *) mem.data;
+ map->capacity = 0;
+ map->size = 0;
+ map->immutable = 0;
+ map->table = NULL;
+
+ GUARD_RESULT_PTR(s2n_map_embiggen(map, capacity));
+
+ return map;
+}
+
+S2N_RESULT s2n_map_add(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value)
+{
+ ENSURE(!map->immutable, S2N_ERR_MAP_IMMUTABLE);
+
+ if (map->capacity < (map->size * 2)) {
+ /* Embiggen the map */
+ GUARD_RESULT(s2n_map_embiggen(map, map->capacity * 2));
+ }
+
+ uint32_t slot = 0;
+ GUARD_RESULT(s2n_map_slot(map, key, &slot));
+
+ /* Linear probing until we find an empty slot */
+ while(map->table[slot].key.size) {
+ if (key->size != map->table[slot].key.size ||
+ memcmp(key->data, map->table[slot].key.data, key->size)) {
+ slot++;
+ slot %= map->capacity;
+ continue;
+ }
+
+ /* We found a duplicate key */
+ BAIL(S2N_ERR_MAP_DUPLICATE);
+ }
+
+ GUARD_AS_RESULT(s2n_dup(key, &map->table[slot].key));
+ GUARD_AS_RESULT(s2n_dup(value, &map->table[slot].value));
+ map->size++;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_map_put(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value)
+{
+ ENSURE(!map->immutable, S2N_ERR_MAP_IMMUTABLE);
+
+ if (map->capacity < (map->size * 2)) {
+ /* Embiggen the map */
+ GUARD_RESULT(s2n_map_embiggen(map, map->capacity * 2));
+ }
+
+ uint32_t slot = 0;
+ GUARD_RESULT(s2n_map_slot(map, key, &slot));
+
+ /* Linear probing until we find an empty slot */
+ while(map->table[slot].key.size) {
+ if (key->size != map->table[slot].key.size ||
+ memcmp(key->data, map->table[slot].key.data, key->size)) {
+ slot++;
+ slot %= map->capacity;
+ continue;
+ }
+
+ /* We found a duplicate key that will be overwritten */
+ GUARD_AS_RESULT(s2n_free(&map->table[slot].key));
+ GUARD_AS_RESULT(s2n_free(&map->table[slot].value));
+ map->size--;
+ break;
+ }
+
+ GUARD_AS_RESULT(s2n_dup(key, &map->table[slot].key));
+ GUARD_AS_RESULT(s2n_dup(value, &map->table[slot].value));
+ map->size++;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_map_complete(struct s2n_map *map)
+{
+ map->immutable = 1;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_map_unlock(struct s2n_map *map)
+{
+ map->immutable = 0;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_map_lookup(const struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value, bool *key_found)
+{
+ ENSURE(map->immutable, S2N_ERR_MAP_MUTABLE);
+
+ uint32_t slot = 0;
+ GUARD_RESULT(s2n_map_slot(map, key, &slot));
+ const uint32_t initial_slot = slot;
+
+ while(map->table[slot].key.size) {
+ if (key->size != map->table[slot].key.size ||
+ memcmp(key->data, map->table[slot].key.data, key->size)) {
+ slot++;
+ slot %= map->capacity;
+ /* We went over all the slots but found no match */
+ if (slot == initial_slot) {
+ break;
+ }
+ continue;
+ }
+
+ /* We found a match */
+ value->data = map->table[slot].value.data;
+ value->size = map->table[slot].value.size;
+
+ *key_found = true;
+
+ return S2N_RESULT_OK;
+ }
+
+ *key_found = false;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_map_free(struct s2n_map *map)
+{
+ /* Free the keys and values */
+ for (int i = 0; i < map->capacity; i++) {
+ if (map->table[i].key.size) {
+ GUARD_AS_RESULT(s2n_free(&map->table[i].key));
+ GUARD_AS_RESULT(s2n_free(&map->table[i].value));
+ }
+ }
+
+ /* Free the table */
+ GUARD_AS_RESULT(s2n_free_object((uint8_t **)&map->table, map->capacity * sizeof(struct s2n_map_entry)));
+
+ /* And finally the map */
+ GUARD_AS_RESULT(s2n_free_object((uint8_t **)&map, sizeof(struct s2n_map)));
+
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_map.h b/contrib/restricted/aws/s2n/utils/s2n_map.h
index afde6a8514..85186581bd 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_map.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_map.h
@@ -1,33 +1,33 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <string.h>
-
-#include "crypto/s2n_hash.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-struct s2n_map;
-
-extern struct s2n_map *s2n_map_new();
-extern struct s2n_map *s2n_map_new_with_initial_capacity(uint32_t capacity);
-extern S2N_RESULT s2n_map_add(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value);
-extern S2N_RESULT s2n_map_put(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value);
-extern S2N_RESULT s2n_map_complete(struct s2n_map *map);
-extern S2N_RESULT s2n_map_unlock(struct s2n_map *map);
-extern S2N_RESULT s2n_map_lookup(const struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value, bool *key_found);
-extern S2N_RESULT s2n_map_free(struct s2n_map *map);
+/*
+ * 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.
+ */
+#pragma once
+
+#include <string.h>
+
+#include "crypto/s2n_hash.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+struct s2n_map;
+
+extern struct s2n_map *s2n_map_new();
+extern struct s2n_map *s2n_map_new_with_initial_capacity(uint32_t capacity);
+extern S2N_RESULT s2n_map_add(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value);
+extern S2N_RESULT s2n_map_put(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value);
+extern S2N_RESULT s2n_map_complete(struct s2n_map *map);
+extern S2N_RESULT s2n_map_unlock(struct s2n_map *map);
+extern S2N_RESULT s2n_map_lookup(const struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value, bool *key_found);
+extern S2N_RESULT s2n_map_free(struct s2n_map *map);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_map_internal.h b/contrib/restricted/aws/s2n/utils/s2n_map_internal.h
index 01d629fb16..13191d70c4 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_map_internal.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_map_internal.h
@@ -1,36 +1,36 @@
-/*
- * 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.
- */
-#pragma once
-
-#include "utils/s2n_map.h"
-
-struct s2n_map_entry {
- struct s2n_blob key;
- struct s2n_blob value;
-};
-
-struct s2n_map {
- /* The total capacity of the table, in number of elements. */
- uint32_t capacity;
-
- /* The total number of elements currently in the table. Used for measuring the load factor */
- uint32_t size;
-
- /* Once a map has been looked up, it is considered immutable */
- int immutable;
-
- /* Pointer to the hash-table, should be capacity * sizeof(struct s2n_map_entry) */
- struct s2n_map_entry *table;
-};
+/*
+ * 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.
+ */
+#pragma once
+
+#include "utils/s2n_map.h"
+
+struct s2n_map_entry {
+ struct s2n_blob key;
+ struct s2n_blob value;
+};
+
+struct s2n_map {
+ /* The total capacity of the table, in number of elements. */
+ uint32_t capacity;
+
+ /* The total number of elements currently in the table. Used for measuring the load factor */
+ uint32_t size;
+
+ /* Once a map has been looked up, it is considered immutable */
+ int immutable;
+
+ /* Pointer to the hash-table, should be capacity * sizeof(struct s2n_map_entry) */
+ struct s2n_map_entry *table;
+};
diff --git a/contrib/restricted/aws/s2n/utils/s2n_mem.c b/contrib/restricted/aws/s2n/utils/s2n_mem.c
index dc14847851..abc9481fa6 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_mem.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_mem.c
@@ -1,304 +1,304 @@
-/*
- * 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.
- */
-
-#define _DEFAULT_SOURCE 1
-#if !defined(__APPLE__) && !defined(__FreeBSD__)
-#include <features.h>
-#endif
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include "error/s2n_errno.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-static uint32_t page_size = 4096;
-static bool initialized = false;
-
-static int s2n_mem_init_impl(void);
-static int s2n_mem_cleanup_impl(void);
-static int s2n_mem_free_no_mlock_impl(void *ptr, uint32_t size);
-static int s2n_mem_free_mlock_impl(void *ptr, uint32_t size);
-static int s2n_mem_malloc_no_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated);
-static int s2n_mem_malloc_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated);
-
-static s2n_mem_init_callback s2n_mem_init_cb = s2n_mem_init_impl;
-static s2n_mem_cleanup_callback s2n_mem_cleanup_cb = s2n_mem_cleanup_impl;
-static s2n_mem_malloc_callback s2n_mem_malloc_cb = s2n_mem_malloc_mlock_impl;
-static s2n_mem_free_callback s2n_mem_free_cb = s2n_mem_free_mlock_impl;
-
-static int s2n_mem_init_impl(void)
-{
- long sysconf_rc = sysconf(_SC_PAGESIZE);
-
- /* sysconf must not error, and page_size cannot be 0 */
- ENSURE_POSIX(sysconf_rc > 0, S2N_FAILURE);
-
- /* page_size must be a valid uint32 */
- ENSURE_POSIX(sysconf_rc <= UINT32_MAX, S2N_FAILURE);
-
- page_size = (uint32_t) sysconf_rc;
-
- if (getenv("S2N_DONT_MLOCK")) {
- s2n_mem_malloc_cb = s2n_mem_malloc_no_mlock_impl;
- s2n_mem_free_cb = s2n_mem_free_no_mlock_impl;
- }
- return S2N_SUCCESS;
-}
-
-static int s2n_mem_cleanup_impl(void)
-{
- page_size = 4096;
- s2n_mem_malloc_cb = s2n_mem_malloc_no_mlock_impl;
- s2n_mem_free_cb = s2n_mem_free_no_mlock_impl;
- return S2N_SUCCESS;
-}
-
-static int s2n_mem_free_mlock_impl(void *ptr, uint32_t size)
-{
- int munlock_rc = munlock(ptr, size);
- free(ptr);
- GUARD(munlock_rc);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_mem_free_no_mlock_impl(void *ptr, uint32_t size)
-{
- free(ptr);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_mem_malloc_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated)
-{
- notnull_check(ptr);
-
- /* Page aligned allocation required for mlock */
- uint32_t allocate;
-
- GUARD(s2n_align_to(requested, page_size, &allocate));
-
- *ptr = NULL;
- S2N_ERROR_IF(posix_memalign(ptr, page_size, allocate) != 0, S2N_ERR_ALLOC);
- *allocated = allocate;
-
-/*
-** We disable MAD_DONTDUMP when fuzz-testing or using the address sanitizer because
-** both need to be able to dump pages to function. It's how they map heap output.
-*/
-#if defined(MADV_DONTDUMP) && !defined(S2N_ADDRESS_SANITIZER) && !defined(S2N_FUZZ_TESTING)
- if (madvise(*ptr, *allocated, MADV_DONTDUMP) != 0) {
- GUARD(s2n_mem_free_no_mlock_impl(*ptr, *allocated));
- S2N_ERROR(S2N_ERR_MADVISE);
- }
-#endif
-
- if (mlock(*ptr, *allocated) != 0) {
- /* When mlock fails, no memory will be locked, so we don't use munlock on free */
- GUARD(s2n_mem_free_no_mlock_impl(*ptr, *allocated));
- S2N_ERROR(S2N_ERR_MLOCK);
- }
-
- S2N_ERROR_IF(*ptr == NULL, S2N_ERR_ALLOC);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_mem_malloc_no_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated)
-{
- *ptr = malloc(requested);
- S2N_ERROR_IF(*ptr == NULL, S2N_ERR_ALLOC);
- *allocated = requested;
-
- return S2N_SUCCESS;
-}
-
-int s2n_mem_set_callbacks(s2n_mem_init_callback mem_init_callback, s2n_mem_cleanup_callback mem_cleanup_callback,
- s2n_mem_malloc_callback mem_malloc_callback, s2n_mem_free_callback mem_free_callback)
-{
- S2N_ERROR_IF(initialized == true, S2N_ERR_INITIALIZED);
-
- notnull_check(mem_init_callback);
- notnull_check(mem_cleanup_callback);
- notnull_check(mem_malloc_callback);
- notnull_check(mem_free_callback);
-
- s2n_mem_init_cb = mem_init_callback;
- s2n_mem_cleanup_cb = mem_cleanup_callback;
- s2n_mem_malloc_cb = mem_malloc_callback;
- s2n_mem_free_cb = mem_free_callback;
-
- return S2N_SUCCESS;
-}
-
-int s2n_alloc(struct s2n_blob *b, uint32_t size)
-{
- S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
- notnull_check(b);
- const struct s2n_blob temp = {0};
- *b = temp;
- GUARD(s2n_realloc(b, size));
- return S2N_SUCCESS;
-}
-
-/* A blob is growable if it is either explicitly marked as such, or if it contains no data */
-bool s2n_blob_is_growable(const struct s2n_blob* b)
-{
- return b && (b->growable || (b->data == NULL && b->size == 0 && b->allocated == 0));
-}
-
-/* Tries to realloc the requested bytes.
- * If successful, updates *b.
- * If failed, *b remains unchanged
- */
-int s2n_realloc(struct s2n_blob *b, uint32_t size)
-{
- S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
- notnull_check(b);
- S2N_ERROR_IF(!s2n_blob_is_growable(b), S2N_ERR_RESIZE_STATIC_BLOB);
- if (size == 0) {
- return s2n_free(b);
- }
-
- /* blob already has space for the request */
- if (size <= b->allocated) {
-
- if (size < b->size) {
- /* Zero the existing blob memory before the we release it */
- struct s2n_blob slice = {0};
- GUARD(s2n_blob_slice(b, &slice, size, b->size - size));
- GUARD(s2n_blob_zero(&slice));
- }
-
- b->size = size;
- return S2N_SUCCESS;
- }
-
- struct s2n_blob new_memory = {.data = NULL, .size = size, .allocated = 0, .growable = 1};
- if(s2n_mem_malloc_cb((void **) &new_memory.data, new_memory.size, &new_memory.allocated) != 0) {
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- S2N_ERROR_IF(new_memory.allocated < new_memory.size, S2N_ERR_ALLOC);
- S2N_ERROR_IF(new_memory.data == NULL, S2N_ERR_ALLOC);
-
- if (b->size) {
- memcpy_check(new_memory.data, b->data, b->size);
- }
-
- if (b->allocated) {
- GUARD(s2n_free(b));
- }
-
- *b = new_memory;
- return S2N_SUCCESS;
-}
-
-int s2n_free_object(uint8_t **p_data, uint32_t size)
-{
- notnull_check(p_data);
-
- if (*p_data == NULL) {
- return S2N_SUCCESS;
- }
- struct s2n_blob b = {.data = *p_data, .allocated = size, .size = size, .growable = 1};
-
- /* s2n_free() will call free() even if it returns error (for a growable blob).
- ** This makes sure *p_data is not used after free() */
- *p_data = NULL;
-
- return s2n_free(&b);
-}
-
-int s2n_dup(struct s2n_blob *from, struct s2n_blob *to)
-{
- S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
- eq_check(to->size, 0);
- eq_check(to->data, NULL);
- ne_check(from->size, 0);
- ne_check(from->data, NULL);
-
- GUARD(s2n_alloc(to, from->size));
-
- memcpy_check(to->data, from->data, to->size);
-
- return S2N_SUCCESS;
-}
-
-int s2n_mem_init(void)
-{
- GUARD(s2n_mem_init_cb());
-
- initialized = true;
-
- return S2N_SUCCESS;
-}
-
-bool s2n_mem_is_init(void)
-{
- return initialized;
-}
-
-uint32_t s2n_mem_get_page_size(void)
-{
- return page_size;
-}
-
-int s2n_mem_cleanup(void)
-{
- S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
- GUARD(s2n_mem_cleanup_cb());
-
- initialized = false;
-
- return S2N_SUCCESS;
-}
-
-int s2n_free(struct s2n_blob *b)
-{
- PRECONDITION_POSIX(s2n_blob_validate(b));
-
- /* To avoid memory leaks, don't exit the function until the memory
- has been freed */
- int zero_rc = s2n_blob_zero(b);
-
- S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
- S2N_ERROR_IF(!s2n_blob_is_growable(b), S2N_ERR_FREE_STATIC_BLOB);
-
- GUARD(s2n_mem_free_cb(b->data, b->allocated));
-
- *b = (struct s2n_blob) {0};
-
- GUARD(zero_rc);
-
- return S2N_SUCCESS;
-}
-
-int s2n_blob_zeroize_free(struct s2n_blob *b) {
- S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
- notnull_check(b);
-
- GUARD(s2n_blob_zero(b));
- if (b->allocated) {
- GUARD(s2n_free(b));
- }
- return S2N_SUCCESS;
-}
+/*
+ * 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.
+ */
+
+#define _DEFAULT_SOURCE 1
+#if !defined(__APPLE__) && !defined(__FreeBSD__)
+#include <features.h>
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "error/s2n_errno.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+static uint32_t page_size = 4096;
+static bool initialized = false;
+
+static int s2n_mem_init_impl(void);
+static int s2n_mem_cleanup_impl(void);
+static int s2n_mem_free_no_mlock_impl(void *ptr, uint32_t size);
+static int s2n_mem_free_mlock_impl(void *ptr, uint32_t size);
+static int s2n_mem_malloc_no_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated);
+static int s2n_mem_malloc_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated);
+
+static s2n_mem_init_callback s2n_mem_init_cb = s2n_mem_init_impl;
+static s2n_mem_cleanup_callback s2n_mem_cleanup_cb = s2n_mem_cleanup_impl;
+static s2n_mem_malloc_callback s2n_mem_malloc_cb = s2n_mem_malloc_mlock_impl;
+static s2n_mem_free_callback s2n_mem_free_cb = s2n_mem_free_mlock_impl;
+
+static int s2n_mem_init_impl(void)
+{
+ long sysconf_rc = sysconf(_SC_PAGESIZE);
+
+ /* sysconf must not error, and page_size cannot be 0 */
+ ENSURE_POSIX(sysconf_rc > 0, S2N_FAILURE);
+
+ /* page_size must be a valid uint32 */
+ ENSURE_POSIX(sysconf_rc <= UINT32_MAX, S2N_FAILURE);
+
+ page_size = (uint32_t) sysconf_rc;
+
+ if (getenv("S2N_DONT_MLOCK")) {
+ s2n_mem_malloc_cb = s2n_mem_malloc_no_mlock_impl;
+ s2n_mem_free_cb = s2n_mem_free_no_mlock_impl;
+ }
+ return S2N_SUCCESS;
+}
+
+static int s2n_mem_cleanup_impl(void)
+{
+ page_size = 4096;
+ s2n_mem_malloc_cb = s2n_mem_malloc_no_mlock_impl;
+ s2n_mem_free_cb = s2n_mem_free_no_mlock_impl;
+ return S2N_SUCCESS;
+}
+
+static int s2n_mem_free_mlock_impl(void *ptr, uint32_t size)
+{
+ int munlock_rc = munlock(ptr, size);
+ free(ptr);
+ GUARD(munlock_rc);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_mem_free_no_mlock_impl(void *ptr, uint32_t size)
+{
+ free(ptr);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_mem_malloc_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated)
+{
+ notnull_check(ptr);
+
+ /* Page aligned allocation required for mlock */
+ uint32_t allocate;
+
+ GUARD(s2n_align_to(requested, page_size, &allocate));
+
+ *ptr = NULL;
+ S2N_ERROR_IF(posix_memalign(ptr, page_size, allocate) != 0, S2N_ERR_ALLOC);
+ *allocated = allocate;
+
+/*
+** We disable MAD_DONTDUMP when fuzz-testing or using the address sanitizer because
+** both need to be able to dump pages to function. It's how they map heap output.
+*/
+#if defined(MADV_DONTDUMP) && !defined(S2N_ADDRESS_SANITIZER) && !defined(S2N_FUZZ_TESTING)
+ if (madvise(*ptr, *allocated, MADV_DONTDUMP) != 0) {
+ GUARD(s2n_mem_free_no_mlock_impl(*ptr, *allocated));
+ S2N_ERROR(S2N_ERR_MADVISE);
+ }
+#endif
+
+ if (mlock(*ptr, *allocated) != 0) {
+ /* When mlock fails, no memory will be locked, so we don't use munlock on free */
+ GUARD(s2n_mem_free_no_mlock_impl(*ptr, *allocated));
+ S2N_ERROR(S2N_ERR_MLOCK);
+ }
+
+ S2N_ERROR_IF(*ptr == NULL, S2N_ERR_ALLOC);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_mem_malloc_no_mlock_impl(void **ptr, uint32_t requested, uint32_t *allocated)
+{
+ *ptr = malloc(requested);
+ S2N_ERROR_IF(*ptr == NULL, S2N_ERR_ALLOC);
+ *allocated = requested;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_mem_set_callbacks(s2n_mem_init_callback mem_init_callback, s2n_mem_cleanup_callback mem_cleanup_callback,
+ s2n_mem_malloc_callback mem_malloc_callback, s2n_mem_free_callback mem_free_callback)
+{
+ S2N_ERROR_IF(initialized == true, S2N_ERR_INITIALIZED);
+
+ notnull_check(mem_init_callback);
+ notnull_check(mem_cleanup_callback);
+ notnull_check(mem_malloc_callback);
+ notnull_check(mem_free_callback);
+
+ s2n_mem_init_cb = mem_init_callback;
+ s2n_mem_cleanup_cb = mem_cleanup_callback;
+ s2n_mem_malloc_cb = mem_malloc_callback;
+ s2n_mem_free_cb = mem_free_callback;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_alloc(struct s2n_blob *b, uint32_t size)
+{
+ S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
+ notnull_check(b);
+ const struct s2n_blob temp = {0};
+ *b = temp;
+ GUARD(s2n_realloc(b, size));
+ return S2N_SUCCESS;
+}
+
+/* A blob is growable if it is either explicitly marked as such, or if it contains no data */
+bool s2n_blob_is_growable(const struct s2n_blob* b)
+{
+ return b && (b->growable || (b->data == NULL && b->size == 0 && b->allocated == 0));
+}
+
+/* Tries to realloc the requested bytes.
+ * If successful, updates *b.
+ * If failed, *b remains unchanged
+ */
+int s2n_realloc(struct s2n_blob *b, uint32_t size)
+{
+ S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
+ notnull_check(b);
+ S2N_ERROR_IF(!s2n_blob_is_growable(b), S2N_ERR_RESIZE_STATIC_BLOB);
+ if (size == 0) {
+ return s2n_free(b);
+ }
+
+ /* blob already has space for the request */
+ if (size <= b->allocated) {
+
+ if (size < b->size) {
+ /* Zero the existing blob memory before the we release it */
+ struct s2n_blob slice = {0};
+ GUARD(s2n_blob_slice(b, &slice, size, b->size - size));
+ GUARD(s2n_blob_zero(&slice));
+ }
+
+ b->size = size;
+ return S2N_SUCCESS;
+ }
+
+ struct s2n_blob new_memory = {.data = NULL, .size = size, .allocated = 0, .growable = 1};
+ if(s2n_mem_malloc_cb((void **) &new_memory.data, new_memory.size, &new_memory.allocated) != 0) {
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ S2N_ERROR_IF(new_memory.allocated < new_memory.size, S2N_ERR_ALLOC);
+ S2N_ERROR_IF(new_memory.data == NULL, S2N_ERR_ALLOC);
+
+ if (b->size) {
+ memcpy_check(new_memory.data, b->data, b->size);
+ }
+
+ if (b->allocated) {
+ GUARD(s2n_free(b));
+ }
+
+ *b = new_memory;
+ return S2N_SUCCESS;
+}
+
+int s2n_free_object(uint8_t **p_data, uint32_t size)
+{
+ notnull_check(p_data);
+
+ if (*p_data == NULL) {
+ return S2N_SUCCESS;
+ }
+ struct s2n_blob b = {.data = *p_data, .allocated = size, .size = size, .growable = 1};
+
+ /* s2n_free() will call free() even if it returns error (for a growable blob).
+ ** This makes sure *p_data is not used after free() */
+ *p_data = NULL;
+
+ return s2n_free(&b);
+}
+
+int s2n_dup(struct s2n_blob *from, struct s2n_blob *to)
+{
+ S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
+ eq_check(to->size, 0);
+ eq_check(to->data, NULL);
+ ne_check(from->size, 0);
+ ne_check(from->data, NULL);
+
+ GUARD(s2n_alloc(to, from->size));
+
+ memcpy_check(to->data, from->data, to->size);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_mem_init(void)
+{
+ GUARD(s2n_mem_init_cb());
+
+ initialized = true;
+
+ return S2N_SUCCESS;
+}
+
+bool s2n_mem_is_init(void)
+{
+ return initialized;
+}
+
+uint32_t s2n_mem_get_page_size(void)
+{
+ return page_size;
+}
+
+int s2n_mem_cleanup(void)
+{
+ S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
+ GUARD(s2n_mem_cleanup_cb());
+
+ initialized = false;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_free(struct s2n_blob *b)
+{
+ PRECONDITION_POSIX(s2n_blob_validate(b));
+
+ /* To avoid memory leaks, don't exit the function until the memory
+ has been freed */
+ int zero_rc = s2n_blob_zero(b);
+
+ S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
+ S2N_ERROR_IF(!s2n_blob_is_growable(b), S2N_ERR_FREE_STATIC_BLOB);
+
+ GUARD(s2n_mem_free_cb(b->data, b->allocated));
+
+ *b = (struct s2n_blob) {0};
+
+ GUARD(zero_rc);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_blob_zeroize_free(struct s2n_blob *b) {
+ S2N_ERROR_IF(initialized == false, S2N_ERR_NOT_INITIALIZED);
+ notnull_check(b);
+
+ GUARD(s2n_blob_zero(b));
+ if (b->allocated) {
+ GUARD(s2n_free(b));
+ }
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_mem.h b/contrib/restricted/aws/s2n/utils/s2n_mem.h
index 78d600db32..91c20871f6 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_mem.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_mem.h
@@ -1,31 +1,31 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "utils/s2n_blob.h"
-
-#include <stdint.h>
-
-int s2n_mem_init(void);
-bool s2n_mem_is_init(void);
-uint32_t s2n_mem_get_page_size(void);
-int s2n_mem_cleanup(void);
-int s2n_alloc(struct s2n_blob *b, uint32_t size);
-int s2n_realloc(struct s2n_blob *b, uint32_t size);
-int s2n_free(struct s2n_blob *b);
-int s2n_blob_zeroize_free(struct s2n_blob *b);
-int s2n_free_object(uint8_t **p_data, uint32_t size);
-int s2n_dup(struct s2n_blob *from, struct s2n_blob *to);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "utils/s2n_blob.h"
+
+#include <stdint.h>
+
+int s2n_mem_init(void);
+bool s2n_mem_is_init(void);
+uint32_t s2n_mem_get_page_size(void);
+int s2n_mem_cleanup(void);
+int s2n_alloc(struct s2n_blob *b, uint32_t size);
+int s2n_realloc(struct s2n_blob *b, uint32_t size);
+int s2n_free(struct s2n_blob *b);
+int s2n_blob_zeroize_free(struct s2n_blob *b);
+int s2n_free_object(uint8_t **p_data, uint32_t size);
+int s2n_dup(struct s2n_blob *from, struct s2n_blob *to);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_random.c b/contrib/restricted/aws/s2n/utils/s2n_random.c
index be063883d0..e68dc14370 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_random.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_random.c
@@ -1,548 +1,548 @@
-/*
- * 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 <openssl/engine.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-
-#include "s2n.h"
-
-#if defined(S2N_CPUID_AVAILABLE)
-#include <cpuid.h>
-#endif
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_drbg.h"
-
-#include "error/s2n_errno.h"
-
-#include "utils/s2n_result.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_mem.h"
-
-#include <openssl/rand.h>
-
-#define ENTROPY_SOURCE "/dev/urandom"
-
-/* See https://en.wikipedia.org/wiki/CPUID */
-#define RDRAND_ECX_FLAG 0x40000000
-
-/* One second in nanoseconds */
-#define ONE_S INT64_C(1000000000)
-
-/* Placeholder value for an uninitialized entropy file descriptor */
-#define UNINITIALIZED_ENTROPY_FD -1
-
-static int entropy_fd = UNINITIALIZED_ENTROPY_FD;
-
-static __thread struct s2n_drbg per_thread_private_drbg = {0};
-static __thread struct s2n_drbg per_thread_public_drbg = {0};
-
-static void *zeroed_when_forked_page;
-static int zero = 0;
-
-static __thread void *zero_if_forked_ptr = &zero;
-#define zero_if_forked (* (int *) zero_if_forked_ptr)
-
-static int s2n_rand_init_impl(void);
-static int s2n_rand_cleanup_impl(void);
-static int s2n_rand_urandom_impl(void *ptr, uint32_t size);
-static int s2n_rand_rdrand_impl(void *ptr, uint32_t size);
-
-static s2n_rand_init_callback s2n_rand_init_cb = s2n_rand_init_impl;
-static s2n_rand_cleanup_callback s2n_rand_cleanup_cb = s2n_rand_cleanup_impl;
-static s2n_rand_seed_callback s2n_rand_seed_cb = s2n_rand_urandom_impl;
-static s2n_rand_mix_callback s2n_rand_mix_cb = s2n_rand_urandom_impl;
-
-bool s2n_cpu_supports_rdrand() {
-#if defined(S2N_CPUID_AVAILABLE)
- uint32_t eax, ebx, ecx, edx;
- if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
- return false;
- }
-
- if (ecx & RDRAND_ECX_FLAG) {
- return true;
- }
-#endif
- return false;
-}
-
-int s2n_rand_set_callbacks(s2n_rand_init_callback rand_init_callback,
- s2n_rand_cleanup_callback rand_cleanup_callback,
- s2n_rand_seed_callback rand_seed_callback,
- s2n_rand_mix_callback rand_mix_callback)
-{
- s2n_rand_init_cb = rand_init_callback;
- s2n_rand_cleanup_cb = rand_cleanup_callback;
- s2n_rand_seed_cb = rand_seed_callback;
- s2n_rand_mix_cb = rand_mix_callback;
-
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_get_seed_entropy(struct s2n_blob *blob)
-{
- ENSURE_REF(blob);
-
- GUARD_AS_RESULT(s2n_rand_seed_cb(blob->data, blob->size));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_get_mix_entropy(struct s2n_blob *blob)
-{
- ENSURE_REF(blob);
-
- GUARD_AS_RESULT(s2n_rand_mix_cb(blob->data, blob->size));
-
- return S2N_RESULT_OK;
-}
-
-void s2n_on_fork(void)
-{
- zero_if_forked = 0;
-}
-
-static inline S2N_RESULT s2n_defend_if_forked(void)
-{
- uint8_t s2n_public_drbg[] = "s2n public drbg";
- uint8_t s2n_private_drbg[] = "s2n private drbg";
- struct s2n_blob public = {.data = s2n_public_drbg,.size = sizeof(s2n_public_drbg) };
- struct s2n_blob private = {.data = s2n_private_drbg,.size = sizeof(s2n_private_drbg) };
-
- if (zero_if_forked == 0) {
- /* Clean up the old drbg first */
- GUARD_RESULT(s2n_rand_cleanup_thread());
- /* Instantiate the new ones */
- GUARD_AS_RESULT(s2n_drbg_instantiate(&per_thread_public_drbg, &public, S2N_AES_128_CTR_NO_DF_PR));
- GUARD_AS_RESULT(s2n_drbg_instantiate(&per_thread_private_drbg, &private, S2N_AES_128_CTR_NO_DF_PR));
- zero_if_forked_ptr = zeroed_when_forked_page;
- zero_if_forked = 1;
- }
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_get_public_random_data(struct s2n_blob *blob)
-{
- GUARD_RESULT(s2n_defend_if_forked());
-
- uint32_t offset = 0;
- uint32_t remaining = blob->size;
-
- while(remaining) {
- struct s2n_blob slice = { 0 };
-
- GUARD_AS_RESULT(s2n_blob_slice(blob, &slice, offset, MIN(remaining, S2N_DRBG_GENERATE_LIMIT)));;
-
- GUARD_AS_RESULT(s2n_drbg_generate(&per_thread_public_drbg, &slice));
-
- remaining -= slice.size;
- offset += slice.size;
- }
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_get_private_random_data(struct s2n_blob *blob)
-{
- GUARD_RESULT(s2n_defend_if_forked());
-
- uint32_t offset = 0;
- uint32_t remaining = blob->size;
-
- while(remaining) {
- struct s2n_blob slice = { 0 };
-
- GUARD_AS_RESULT(s2n_blob_slice(blob, &slice, offset, MIN(remaining, S2N_DRBG_GENERATE_LIMIT)));;
-
- GUARD_AS_RESULT(s2n_drbg_generate(&per_thread_private_drbg, &slice));
-
- remaining -= slice.size;
- offset += slice.size;
- }
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_get_public_random_bytes_used(uint64_t *bytes_used)
-{
- GUARD_AS_RESULT(s2n_drbg_bytes_used(&per_thread_public_drbg, bytes_used));
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used)
-{
- GUARD_AS_RESULT(s2n_drbg_bytes_used(&per_thread_private_drbg, bytes_used));
- return S2N_RESULT_OK;
-}
-
-static int s2n_rand_urandom_impl(void *ptr, uint32_t size)
-{
- ENSURE_POSIX(entropy_fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED);
-
- uint8_t *data = ptr;
- uint32_t n = size;
- struct timespec sleep_time = {.tv_sec = 0, .tv_nsec = 0 };
- long backoff = 1;
-
- while (n) {
- errno = 0;
- int r = read(entropy_fd, data, n);
- if (r <= 0) {
- /*
- * A non-blocking read() on /dev/urandom should "never" fail,
- * except for EINTR. If it does, briefly pause and use
- * exponential backoff to avoid creating a tight spinning loop.
- *
- * iteration delay
- * --------- -----------------
- * 1 10 nsec
- * 2 100 nsec
- * 3 1,000 nsec
- * 4 10,000 nsec
- * 5 100,000 nsec
- * 6 1,000,000 nsec
- * 7 10,000,000 nsec
- * 8 99,999,999 nsec
- * 9 99,999,999 nsec
- * ...
- */
- if (errno != EINTR) {
- backoff = MIN(backoff * 10, ONE_S - 1);
- sleep_time.tv_nsec = backoff;
- do {
- r = nanosleep(&sleep_time, &sleep_time);
- }
- while (r != 0);
- }
-
- continue;
- }
-
- data += r;
- n -= r;
- }
-
- return S2N_SUCCESS;
-}
-
-/*
- * Return a random number in the range [0, bound)
- */
-S2N_RESULT s2n_public_random(int64_t bound, uint64_t *output)
-{
- uint64_t r;
-
- ENSURE_GT(bound, 0);
-
- while (1) {
- struct s2n_blob blob = {.data = (void *)&r, sizeof(r) };
- GUARD_RESULT(s2n_get_public_random_data(&blob));
-
- /* Imagine an int was one byte and UINT_MAX was 256. If the
- * caller asked for s2n_random(129, ...) we'd end up in
- * trouble. Each number in the range 0...127 would be twice
- * as likely as 128. That's because r == 0 % 129 -> 0, and
- * r == 129 % 129 -> 0, but only r == 128 returns 128,
- * r == 257 is out of range.
- *
- * To de-bias the dice, we discard values of r that are higher
- * that the highest multiple of 'bound' an int can support. If
- * bound is a uint, then in the worst case we discard 50% - 1 r's.
- * But since 'bound' is an int and INT_MAX is <= UINT_MAX / 2,
- * in the worst case we discard 25% - 1 r's.
- */
- if (r < (UINT64_MAX - (UINT64_MAX % bound))) {
- *output = r % bound;
- return S2N_RESULT_OK;
- }
- }
-}
-
-#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
-
-int s2n_openssl_compat_rand(unsigned char *buf, int num)
-{
- struct s2n_blob out = {.data = buf,.size = num };
-
- if (s2n_result_is_error(s2n_get_private_random_data(&out))) {
- return 0;
- }
- return 1;
-}
-
-int s2n_openssl_compat_status(void)
-{
- return 1;
-}
-
-int s2n_openssl_compat_init(ENGINE * unused)
-{
- return 1;
-}
-
-RAND_METHOD s2n_openssl_rand_method = {
- .seed = NULL,
- .bytes = s2n_openssl_compat_rand,
- .cleanup = NULL,
- .add = NULL,
- .pseudorand = s2n_openssl_compat_rand,
- .status = s2n_openssl_compat_status
-};
-#endif
-
-static int s2n_rand_init_impl(void)
-{
- OPEN:
- entropy_fd = open(ENTROPY_SOURCE, O_RDONLY);
- if (entropy_fd == S2N_FAILURE) {
- if (errno == EINTR) {
- goto OPEN;
- }
- S2N_ERROR(S2N_ERR_OPEN_RANDOM);
- }
-
- if (s2n_cpu_supports_rdrand()) {
- s2n_rand_mix_cb = s2n_rand_rdrand_impl;
- }
-
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_rand_init(void)
-{
- uint32_t pagesize;
-
- GUARD_AS_RESULT(s2n_rand_init_cb());
-
- pagesize = s2n_mem_get_page_size();
-
- /* We need a single-aligned page for our protected memory region */
- ENSURE(posix_memalign(&zeroed_when_forked_page, pagesize, pagesize) == S2N_SUCCESS, S2N_ERR_OPEN_RANDOM);
- ENSURE(zeroed_when_forked_page != NULL, S2N_ERR_OPEN_RANDOM);
-
- /* Initialized to zero to ensure that we seed our DRBGs */
- zero_if_forked = 0;
-
- /* INHERIT_ZERO and WIPEONFORK reset a page to all-zeroes when a fork occurs */
-#if defined(MAP_INHERIT_ZERO)
- ENSURE(minherit(zeroed_when_forked_page, pagesize, MAP_INHERIT_ZERO) != S2N_FAILURE, S2N_ERR_OPEN_RANDOM);
-#endif
-
-#if defined(MADV_WIPEONFORK)
- ENSURE(madvise(zeroed_when_forked_page, pagesize, MADV_WIPEONFORK) == S2N_SUCCESS, S2N_ERR_OPEN_RANDOM);
-#endif
-
- /* For defence in depth */
- ENSURE(pthread_atfork(NULL, NULL, s2n_on_fork) == S2N_SUCCESS, S2N_ERR_OPEN_RANDOM);
-
- /* Seed everything */
- GUARD_RESULT(s2n_defend_if_forked());
-
-#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
- /* Create an engine */
- ENGINE *e = ENGINE_new();
-
- ENSURE(e != NULL, S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_set_id(e, "s2n_rand"), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_set_name(e, "s2n entropy generator"), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_set_init_function(e, s2n_openssl_compat_init), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_set_RAND(e, &s2n_openssl_rand_method), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_add(e), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_free(e) , S2N_ERR_OPEN_RANDOM);
-
- /* Use that engine for rand() */
- e = ENGINE_by_id("s2n_rand");
- ENSURE(e != NULL, S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_init(e), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_set_default(e, ENGINE_METHOD_RAND), S2N_ERR_OPEN_RANDOM);
- GUARD_RESULT_OSSL(ENGINE_free(e), S2N_ERR_OPEN_RANDOM);
-#endif
-
- return S2N_RESULT_OK;
-}
-
-static int s2n_rand_cleanup_impl(void)
-{
- ENSURE_POSIX(entropy_fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED);
-
- GUARD(close(entropy_fd));
- entropy_fd = UNINITIALIZED_ENTROPY_FD;
-
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_rand_cleanup(void)
-{
- GUARD_AS_RESULT(s2n_rand_cleanup_cb());
-
-#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
- /* Cleanup our rand ENGINE in libcrypto */
- ENGINE *rand_engine = ENGINE_by_id("s2n_rand");
- if (rand_engine) {
- ENGINE_finish(rand_engine);
- ENGINE_free(rand_engine);
- ENGINE_cleanup();
- }
-#endif
-
- s2n_rand_init_cb = s2n_rand_init_impl;
- s2n_rand_cleanup_cb = s2n_rand_cleanup_impl;
- s2n_rand_seed_cb = s2n_rand_urandom_impl;
- s2n_rand_mix_cb = s2n_rand_urandom_impl;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_rand_cleanup_thread(void)
-{
- GUARD_AS_RESULT(s2n_drbg_wipe(&per_thread_private_drbg));
- GUARD_AS_RESULT(s2n_drbg_wipe(&per_thread_public_drbg));
-
- return S2N_RESULT_OK;
-}
-
-/*
- * This must only be used for unit tests. Any real use is dangerous and will be overwritten in s2n_defend_if_forked if
- * it is forked. This was added to support known answer tests that use OpenSSL and s2n_get_private_random_data directly.
- */
-S2N_RESULT s2n_set_private_drbg_for_test(struct s2n_drbg drbg)
-{
- ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
- GUARD_AS_RESULT(s2n_drbg_wipe(&per_thread_private_drbg));
-
- per_thread_private_drbg = drbg;
- return S2N_RESULT_OK;
-}
-
-/*
- * volatile is important to prevent the compiler from
- * re-ordering or optimizing the use of RDRAND.
- */
-static int s2n_rand_rdrand_impl(void *data, uint32_t size)
-{
-#if defined(__x86_64__) || defined(__i386__)
- struct s2n_blob out = { .data = data, .size = size };
- int space_remaining = 0;
- struct s2n_stuffer stuffer = {0};
- union {
- uint64_t u64;
-#if defined(__i386__)
- struct {
- /* since we check first that we're on intel, we can safely assume little endian. */
- uint32_t u_low;
- uint32_t u_high;
- } i386_fields;
-#endif /* defined(__i386__) */
- uint8_t u8[8];
- } output;
-
- GUARD(s2n_stuffer_init(&stuffer, &out));
- while ((space_remaining = s2n_stuffer_space_remaining(&stuffer))) {
- unsigned char success = 0;
- output.u64 = 0;
-
- for (int tries = 0; tries < 10; tries++) {
-#if defined(__i386__)
- /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
- * output.i386_fields.u_low). Check the carry bit, which will be set on success. Then clober the register and reset
- * the carry bit. Due to needing to support an ancient assembler we use the opcode syntax.
- * the %b1 is to force compilers to use c1 instead of ecx.
- * Here's a description of how the opcode is encoded:
- * 0x0fc7 (rdrand)
- * 0xf0 (store the result in eax).
- */
- unsigned char success_high = 0, success_low = 0;
- __asm__ __volatile__(".byte 0x0f, 0xc7, 0xf0;\n" "setc %b1;\n": "=a"(output.i386_fields.u_low), "=qm"(success_low)
- :
- :"cc");
-
- __asm__ __volatile__(".byte 0x0f, 0xc7, 0xf0;\n" "setc %b1;\n": "=a"(output.i386_fields.u_high), "=qm"(success_high)
- :
- :"cc");
- /* cppcheck-suppress knownConditionTrueFalse */
- success = success_high & success_low;
-
- /* Treat either all 1 or all 0 bits in either the high or low order
- * bits as failure */
- if (output.i386_fields.u_low == 0 ||
- output.i386_fields.u_low == UINT32_MAX ||
- output.i386_fields.u_high == 0 ||
- output.i386_fields.u_high == UINT32_MAX) {
- success = 0;
- }
-#else
- /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
- * output.u64). Check the carry bit, which will be set on success. Then clober the carry bit.
- * Due to needing to support an ancient assembler we use the opcode syntax.
- * the %b1 is to force compilers to use c1 instead of ecx.
- * Here's a description of how the opcode is encoded:
- * 0x48 (pick a 64-bit register it does more too, but that's all that matters there)
- * 0x0fc7 (rdrand)
- * 0xf0 (store the result in rax). */
- __asm__ __volatile__(".byte 0x48, 0x0f, 0xc7, 0xf0;\n" "setc %b1;\n": "=a"(output.u64), "=qm"(success)
- :
- :"cc");
-#endif /* defined(__i386__) */
-
- /* Some AMD CPUs will find that RDRAND "sticks" on all 1s but still reports success.
- * Some other very old CPUs use all 0s as an error condition while still reporting success.
- * If we encounter either of these suspicious values (a 1/2^63 chance) we'll treat them as
- * a failure and generate a new value.
- *
- * In the future we could add CPUID checks to detect processors with these known bugs,
- * however it does not appear worth it. The entropy loss is negligible and the
- * corresponding likelihood that a healthy CPU generates either of these values is also
- * negligible (1/2^63). Finally, adding processor specific logic would greatly
- * increase the complexity and would cause us to "miss" any unknown processors with
- * similar bugs. */
- if (output.u64 == UINT64_MAX ||
- output.u64 == 0) {
- success = 0;
- }
-
- if (success) {
- break;
- }
- }
-
- ENSURE_POSIX(success, S2N_ERR_RDRAND_FAILED);
-
- int data_to_fill = MIN(sizeof(output), space_remaining);
-
- GUARD_POSIX(s2n_stuffer_write_bytes(&stuffer, output.u8, data_to_fill));
- }
-
- return S2N_SUCCESS;
-#else
- BAIL_POSIX(S2N_ERR_UNSUPPORTED_CPU);
-#endif
-}
+/*
+ * 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 <openssl/engine.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+
+#include "s2n.h"
+
+#if defined(S2N_CPUID_AVAILABLE)
+#include <cpuid.h>
+#endif
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_drbg.h"
+
+#include "error/s2n_errno.h"
+
+#include "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_mem.h"
+
+#include <openssl/rand.h>
+
+#define ENTROPY_SOURCE "/dev/urandom"
+
+/* See https://en.wikipedia.org/wiki/CPUID */
+#define RDRAND_ECX_FLAG 0x40000000
+
+/* One second in nanoseconds */
+#define ONE_S INT64_C(1000000000)
+
+/* Placeholder value for an uninitialized entropy file descriptor */
+#define UNINITIALIZED_ENTROPY_FD -1
+
+static int entropy_fd = UNINITIALIZED_ENTROPY_FD;
+
+static __thread struct s2n_drbg per_thread_private_drbg = {0};
+static __thread struct s2n_drbg per_thread_public_drbg = {0};
+
+static void *zeroed_when_forked_page;
+static int zero = 0;
+
+static __thread void *zero_if_forked_ptr = &zero;
+#define zero_if_forked (* (int *) zero_if_forked_ptr)
+
+static int s2n_rand_init_impl(void);
+static int s2n_rand_cleanup_impl(void);
+static int s2n_rand_urandom_impl(void *ptr, uint32_t size);
+static int s2n_rand_rdrand_impl(void *ptr, uint32_t size);
+
+static s2n_rand_init_callback s2n_rand_init_cb = s2n_rand_init_impl;
+static s2n_rand_cleanup_callback s2n_rand_cleanup_cb = s2n_rand_cleanup_impl;
+static s2n_rand_seed_callback s2n_rand_seed_cb = s2n_rand_urandom_impl;
+static s2n_rand_mix_callback s2n_rand_mix_cb = s2n_rand_urandom_impl;
+
+bool s2n_cpu_supports_rdrand() {
+#if defined(S2N_CPUID_AVAILABLE)
+ uint32_t eax, ebx, ecx, edx;
+ if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
+ return false;
+ }
+
+ if (ecx & RDRAND_ECX_FLAG) {
+ return true;
+ }
+#endif
+ return false;
+}
+
+int s2n_rand_set_callbacks(s2n_rand_init_callback rand_init_callback,
+ s2n_rand_cleanup_callback rand_cleanup_callback,
+ s2n_rand_seed_callback rand_seed_callback,
+ s2n_rand_mix_callback rand_mix_callback)
+{
+ s2n_rand_init_cb = rand_init_callback;
+ s2n_rand_cleanup_cb = rand_cleanup_callback;
+ s2n_rand_seed_cb = rand_seed_callback;
+ s2n_rand_mix_cb = rand_mix_callback;
+
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_get_seed_entropy(struct s2n_blob *blob)
+{
+ ENSURE_REF(blob);
+
+ GUARD_AS_RESULT(s2n_rand_seed_cb(blob->data, blob->size));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_get_mix_entropy(struct s2n_blob *blob)
+{
+ ENSURE_REF(blob);
+
+ GUARD_AS_RESULT(s2n_rand_mix_cb(blob->data, blob->size));
+
+ return S2N_RESULT_OK;
+}
+
+void s2n_on_fork(void)
+{
+ zero_if_forked = 0;
+}
+
+static inline S2N_RESULT s2n_defend_if_forked(void)
+{
+ uint8_t s2n_public_drbg[] = "s2n public drbg";
+ uint8_t s2n_private_drbg[] = "s2n private drbg";
+ struct s2n_blob public = {.data = s2n_public_drbg,.size = sizeof(s2n_public_drbg) };
+ struct s2n_blob private = {.data = s2n_private_drbg,.size = sizeof(s2n_private_drbg) };
+
+ if (zero_if_forked == 0) {
+ /* Clean up the old drbg first */
+ GUARD_RESULT(s2n_rand_cleanup_thread());
+ /* Instantiate the new ones */
+ GUARD_AS_RESULT(s2n_drbg_instantiate(&per_thread_public_drbg, &public, S2N_AES_128_CTR_NO_DF_PR));
+ GUARD_AS_RESULT(s2n_drbg_instantiate(&per_thread_private_drbg, &private, S2N_AES_128_CTR_NO_DF_PR));
+ zero_if_forked_ptr = zeroed_when_forked_page;
+ zero_if_forked = 1;
+ }
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_get_public_random_data(struct s2n_blob *blob)
+{
+ GUARD_RESULT(s2n_defend_if_forked());
+
+ uint32_t offset = 0;
+ uint32_t remaining = blob->size;
+
+ while(remaining) {
+ struct s2n_blob slice = { 0 };
+
+ GUARD_AS_RESULT(s2n_blob_slice(blob, &slice, offset, MIN(remaining, S2N_DRBG_GENERATE_LIMIT)));;
+
+ GUARD_AS_RESULT(s2n_drbg_generate(&per_thread_public_drbg, &slice));
+
+ remaining -= slice.size;
+ offset += slice.size;
+ }
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_get_private_random_data(struct s2n_blob *blob)
+{
+ GUARD_RESULT(s2n_defend_if_forked());
+
+ uint32_t offset = 0;
+ uint32_t remaining = blob->size;
+
+ while(remaining) {
+ struct s2n_blob slice = { 0 };
+
+ GUARD_AS_RESULT(s2n_blob_slice(blob, &slice, offset, MIN(remaining, S2N_DRBG_GENERATE_LIMIT)));;
+
+ GUARD_AS_RESULT(s2n_drbg_generate(&per_thread_private_drbg, &slice));
+
+ remaining -= slice.size;
+ offset += slice.size;
+ }
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_get_public_random_bytes_used(uint64_t *bytes_used)
+{
+ GUARD_AS_RESULT(s2n_drbg_bytes_used(&per_thread_public_drbg, bytes_used));
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used)
+{
+ GUARD_AS_RESULT(s2n_drbg_bytes_used(&per_thread_private_drbg, bytes_used));
+ return S2N_RESULT_OK;
+}
+
+static int s2n_rand_urandom_impl(void *ptr, uint32_t size)
+{
+ ENSURE_POSIX(entropy_fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED);
+
+ uint8_t *data = ptr;
+ uint32_t n = size;
+ struct timespec sleep_time = {.tv_sec = 0, .tv_nsec = 0 };
+ long backoff = 1;
+
+ while (n) {
+ errno = 0;
+ int r = read(entropy_fd, data, n);
+ if (r <= 0) {
+ /*
+ * A non-blocking read() on /dev/urandom should "never" fail,
+ * except for EINTR. If it does, briefly pause and use
+ * exponential backoff to avoid creating a tight spinning loop.
+ *
+ * iteration delay
+ * --------- -----------------
+ * 1 10 nsec
+ * 2 100 nsec
+ * 3 1,000 nsec
+ * 4 10,000 nsec
+ * 5 100,000 nsec
+ * 6 1,000,000 nsec
+ * 7 10,000,000 nsec
+ * 8 99,999,999 nsec
+ * 9 99,999,999 nsec
+ * ...
+ */
+ if (errno != EINTR) {
+ backoff = MIN(backoff * 10, ONE_S - 1);
+ sleep_time.tv_nsec = backoff;
+ do {
+ r = nanosleep(&sleep_time, &sleep_time);
+ }
+ while (r != 0);
+ }
+
+ continue;
+ }
+
+ data += r;
+ n -= r;
+ }
+
+ return S2N_SUCCESS;
+}
+
+/*
+ * Return a random number in the range [0, bound)
+ */
+S2N_RESULT s2n_public_random(int64_t bound, uint64_t *output)
+{
+ uint64_t r;
+
+ ENSURE_GT(bound, 0);
+
+ while (1) {
+ struct s2n_blob blob = {.data = (void *)&r, sizeof(r) };
+ GUARD_RESULT(s2n_get_public_random_data(&blob));
+
+ /* Imagine an int was one byte and UINT_MAX was 256. If the
+ * caller asked for s2n_random(129, ...) we'd end up in
+ * trouble. Each number in the range 0...127 would be twice
+ * as likely as 128. That's because r == 0 % 129 -> 0, and
+ * r == 129 % 129 -> 0, but only r == 128 returns 128,
+ * r == 257 is out of range.
+ *
+ * To de-bias the dice, we discard values of r that are higher
+ * that the highest multiple of 'bound' an int can support. If
+ * bound is a uint, then in the worst case we discard 50% - 1 r's.
+ * But since 'bound' is an int and INT_MAX is <= UINT_MAX / 2,
+ * in the worst case we discard 25% - 1 r's.
+ */
+ if (r < (UINT64_MAX - (UINT64_MAX % bound))) {
+ *output = r % bound;
+ return S2N_RESULT_OK;
+ }
+ }
+}
+
+#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
+
+int s2n_openssl_compat_rand(unsigned char *buf, int num)
+{
+ struct s2n_blob out = {.data = buf,.size = num };
+
+ if (s2n_result_is_error(s2n_get_private_random_data(&out))) {
+ return 0;
+ }
+ return 1;
+}
+
+int s2n_openssl_compat_status(void)
+{
+ return 1;
+}
+
+int s2n_openssl_compat_init(ENGINE * unused)
+{
+ return 1;
+}
+
+RAND_METHOD s2n_openssl_rand_method = {
+ .seed = NULL,
+ .bytes = s2n_openssl_compat_rand,
+ .cleanup = NULL,
+ .add = NULL,
+ .pseudorand = s2n_openssl_compat_rand,
+ .status = s2n_openssl_compat_status
+};
+#endif
+
+static int s2n_rand_init_impl(void)
+{
+ OPEN:
+ entropy_fd = open(ENTROPY_SOURCE, O_RDONLY);
+ if (entropy_fd == S2N_FAILURE) {
+ if (errno == EINTR) {
+ goto OPEN;
+ }
+ S2N_ERROR(S2N_ERR_OPEN_RANDOM);
+ }
+
+ if (s2n_cpu_supports_rdrand()) {
+ s2n_rand_mix_cb = s2n_rand_rdrand_impl;
+ }
+
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_rand_init(void)
+{
+ uint32_t pagesize;
+
+ GUARD_AS_RESULT(s2n_rand_init_cb());
+
+ pagesize = s2n_mem_get_page_size();
+
+ /* We need a single-aligned page for our protected memory region */
+ ENSURE(posix_memalign(&zeroed_when_forked_page, pagesize, pagesize) == S2N_SUCCESS, S2N_ERR_OPEN_RANDOM);
+ ENSURE(zeroed_when_forked_page != NULL, S2N_ERR_OPEN_RANDOM);
+
+ /* Initialized to zero to ensure that we seed our DRBGs */
+ zero_if_forked = 0;
+
+ /* INHERIT_ZERO and WIPEONFORK reset a page to all-zeroes when a fork occurs */
+#if defined(MAP_INHERIT_ZERO)
+ ENSURE(minherit(zeroed_when_forked_page, pagesize, MAP_INHERIT_ZERO) != S2N_FAILURE, S2N_ERR_OPEN_RANDOM);
+#endif
+
+#if defined(MADV_WIPEONFORK)
+ ENSURE(madvise(zeroed_when_forked_page, pagesize, MADV_WIPEONFORK) == S2N_SUCCESS, S2N_ERR_OPEN_RANDOM);
+#endif
+
+ /* For defence in depth */
+ ENSURE(pthread_atfork(NULL, NULL, s2n_on_fork) == S2N_SUCCESS, S2N_ERR_OPEN_RANDOM);
+
+ /* Seed everything */
+ GUARD_RESULT(s2n_defend_if_forked());
+
+#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
+ /* Create an engine */
+ ENGINE *e = ENGINE_new();
+
+ ENSURE(e != NULL, S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_set_id(e, "s2n_rand"), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_set_name(e, "s2n entropy generator"), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_set_init_function(e, s2n_openssl_compat_init), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_set_RAND(e, &s2n_openssl_rand_method), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_add(e), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_free(e) , S2N_ERR_OPEN_RANDOM);
+
+ /* Use that engine for rand() */
+ e = ENGINE_by_id("s2n_rand");
+ ENSURE(e != NULL, S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_init(e), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_set_default(e, ENGINE_METHOD_RAND), S2N_ERR_OPEN_RANDOM);
+ GUARD_RESULT_OSSL(ENGINE_free(e), S2N_ERR_OPEN_RANDOM);
+#endif
+
+ return S2N_RESULT_OK;
+}
+
+static int s2n_rand_cleanup_impl(void)
+{
+ ENSURE_POSIX(entropy_fd != UNINITIALIZED_ENTROPY_FD, S2N_ERR_NOT_INITIALIZED);
+
+ GUARD(close(entropy_fd));
+ entropy_fd = UNINITIALIZED_ENTROPY_FD;
+
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_rand_cleanup(void)
+{
+ GUARD_AS_RESULT(s2n_rand_cleanup_cb());
+
+#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
+ /* Cleanup our rand ENGINE in libcrypto */
+ ENGINE *rand_engine = ENGINE_by_id("s2n_rand");
+ if (rand_engine) {
+ ENGINE_finish(rand_engine);
+ ENGINE_free(rand_engine);
+ ENGINE_cleanup();
+ }
+#endif
+
+ s2n_rand_init_cb = s2n_rand_init_impl;
+ s2n_rand_cleanup_cb = s2n_rand_cleanup_impl;
+ s2n_rand_seed_cb = s2n_rand_urandom_impl;
+ s2n_rand_mix_cb = s2n_rand_urandom_impl;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_rand_cleanup_thread(void)
+{
+ GUARD_AS_RESULT(s2n_drbg_wipe(&per_thread_private_drbg));
+ GUARD_AS_RESULT(s2n_drbg_wipe(&per_thread_public_drbg));
+
+ return S2N_RESULT_OK;
+}
+
+/*
+ * This must only be used for unit tests. Any real use is dangerous and will be overwritten in s2n_defend_if_forked if
+ * it is forked. This was added to support known answer tests that use OpenSSL and s2n_get_private_random_data directly.
+ */
+S2N_RESULT s2n_set_private_drbg_for_test(struct s2n_drbg drbg)
+{
+ ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
+ GUARD_AS_RESULT(s2n_drbg_wipe(&per_thread_private_drbg));
+
+ per_thread_private_drbg = drbg;
+ return S2N_RESULT_OK;
+}
+
+/*
+ * volatile is important to prevent the compiler from
+ * re-ordering or optimizing the use of RDRAND.
+ */
+static int s2n_rand_rdrand_impl(void *data, uint32_t size)
+{
+#if defined(__x86_64__) || defined(__i386__)
+ struct s2n_blob out = { .data = data, .size = size };
+ int space_remaining = 0;
+ struct s2n_stuffer stuffer = {0};
+ union {
+ uint64_t u64;
+#if defined(__i386__)
+ struct {
+ /* since we check first that we're on intel, we can safely assume little endian. */
+ uint32_t u_low;
+ uint32_t u_high;
+ } i386_fields;
+#endif /* defined(__i386__) */
+ uint8_t u8[8];
+ } output;
+
+ GUARD(s2n_stuffer_init(&stuffer, &out));
+ while ((space_remaining = s2n_stuffer_space_remaining(&stuffer))) {
+ unsigned char success = 0;
+ output.u64 = 0;
+
+ for (int tries = 0; tries < 10; tries++) {
+#if defined(__i386__)
+ /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
+ * output.i386_fields.u_low). Check the carry bit, which will be set on success. Then clober the register and reset
+ * the carry bit. Due to needing to support an ancient assembler we use the opcode syntax.
+ * the %b1 is to force compilers to use c1 instead of ecx.
+ * Here's a description of how the opcode is encoded:
+ * 0x0fc7 (rdrand)
+ * 0xf0 (store the result in eax).
+ */
+ unsigned char success_high = 0, success_low = 0;
+ __asm__ __volatile__(".byte 0x0f, 0xc7, 0xf0;\n" "setc %b1;\n": "=a"(output.i386_fields.u_low), "=qm"(success_low)
+ :
+ :"cc");
+
+ __asm__ __volatile__(".byte 0x0f, 0xc7, 0xf0;\n" "setc %b1;\n": "=a"(output.i386_fields.u_high), "=qm"(success_high)
+ :
+ :"cc");
+ /* cppcheck-suppress knownConditionTrueFalse */
+ success = success_high & success_low;
+
+ /* Treat either all 1 or all 0 bits in either the high or low order
+ * bits as failure */
+ if (output.i386_fields.u_low == 0 ||
+ output.i386_fields.u_low == UINT32_MAX ||
+ output.i386_fields.u_high == 0 ||
+ output.i386_fields.u_high == UINT32_MAX) {
+ success = 0;
+ }
+#else
+ /* execute the rdrand instruction, store the result in a general purpose register (it's assigned to
+ * output.u64). Check the carry bit, which will be set on success. Then clober the carry bit.
+ * Due to needing to support an ancient assembler we use the opcode syntax.
+ * the %b1 is to force compilers to use c1 instead of ecx.
+ * Here's a description of how the opcode is encoded:
+ * 0x48 (pick a 64-bit register it does more too, but that's all that matters there)
+ * 0x0fc7 (rdrand)
+ * 0xf0 (store the result in rax). */
+ __asm__ __volatile__(".byte 0x48, 0x0f, 0xc7, 0xf0;\n" "setc %b1;\n": "=a"(output.u64), "=qm"(success)
+ :
+ :"cc");
+#endif /* defined(__i386__) */
+
+ /* Some AMD CPUs will find that RDRAND "sticks" on all 1s but still reports success.
+ * Some other very old CPUs use all 0s as an error condition while still reporting success.
+ * If we encounter either of these suspicious values (a 1/2^63 chance) we'll treat them as
+ * a failure and generate a new value.
+ *
+ * In the future we could add CPUID checks to detect processors with these known bugs,
+ * however it does not appear worth it. The entropy loss is negligible and the
+ * corresponding likelihood that a healthy CPU generates either of these values is also
+ * negligible (1/2^63). Finally, adding processor specific logic would greatly
+ * increase the complexity and would cause us to "miss" any unknown processors with
+ * similar bugs. */
+ if (output.u64 == UINT64_MAX ||
+ output.u64 == 0) {
+ success = 0;
+ }
+
+ if (success) {
+ break;
+ }
+ }
+
+ ENSURE_POSIX(success, S2N_ERR_RDRAND_FAILED);
+
+ int data_to_fill = MIN(sizeof(output), space_remaining);
+
+ GUARD_POSIX(s2n_stuffer_write_bytes(&stuffer, output.u8, data_to_fill));
+ }
+
+ return S2N_SUCCESS;
+#else
+ BAIL_POSIX(S2N_ERR_UNSUPPORTED_CPU);
+#endif
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_random.h b/contrib/restricted/aws/s2n/utils/s2n_random.h
index 1d316328b9..15efe7cd10 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_random.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_random.h
@@ -1,34 +1,34 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "crypto/s2n_drbg.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-extern S2N_RESULT s2n_rand_init(void);
-extern S2N_RESULT s2n_rand_cleanup(void);
-extern S2N_RESULT s2n_get_seed_entropy(struct s2n_blob *blob);
-extern S2N_RESULT s2n_get_mix_entropy(struct s2n_blob *blob);
-
-extern S2N_RESULT s2n_rand_cleanup_thread(void);
-extern S2N_RESULT s2n_set_private_drbg_for_test(struct s2n_drbg drbg);
-extern S2N_RESULT s2n_get_public_random_data(struct s2n_blob *blob);
-extern S2N_RESULT s2n_get_public_random_bytes_used(uint64_t *bytes_used);
-extern S2N_RESULT s2n_get_private_random_data(struct s2n_blob *blob);
-extern S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used);
-extern S2N_RESULT s2n_public_random(int64_t max, uint64_t *output);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "crypto/s2n_drbg.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+extern S2N_RESULT s2n_rand_init(void);
+extern S2N_RESULT s2n_rand_cleanup(void);
+extern S2N_RESULT s2n_get_seed_entropy(struct s2n_blob *blob);
+extern S2N_RESULT s2n_get_mix_entropy(struct s2n_blob *blob);
+
+extern S2N_RESULT s2n_rand_cleanup_thread(void);
+extern S2N_RESULT s2n_set_private_drbg_for_test(struct s2n_drbg drbg);
+extern S2N_RESULT s2n_get_public_random_data(struct s2n_blob *blob);
+extern S2N_RESULT s2n_get_public_random_bytes_used(uint64_t *bytes_used);
+extern S2N_RESULT s2n_get_private_random_data(struct s2n_blob *blob);
+extern S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used);
+extern S2N_RESULT s2n_public_random(int64_t max, uint64_t *output);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_result.c b/contrib/restricted/aws/s2n/utils/s2n_result.c
index 022fcc3711..3f851a0697 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_result.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_result.c
@@ -1,93 +1,93 @@
-/*
- * 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.
- */
-
-/*
- * The goal of s2n_result is to provide a strongly-typed error
- * signal value, which provides the compiler with enough information
- * to catch bugs.
- *
- * Historically, s2n has used int to signal errors. This has caused a few issues:
- *
- * ## GUARD in a function returning integer types
- *
- * There is no compiler error if `GUARD(nested_call());` is used in a function
- * that is meant to return integer type - not a error signal.
- *
- * ```c
- * uint8_t s2n_answer_to_the_ultimate_question() {
- * GUARD(s2n_sleep_for_years(7500000));
- * return 42;
- * }
- * ```
- *
- * In this function we intended to return a `uint8_t` but used a
- * `GUARD` which will return -1 if the call fails. This can lead to
- * very subtle bugs.
- *
- * ## `GUARD`ing a function returning any integer type
- *
- * There is no compiler error if `GUARD(nested_call());` is used
- * on a function that doesn't actually return an error signal
- *
- * ```c
- * int s2n_deep_thought() {
- * GUARD(s2n_answer_to_the_ultimate_question());
- * return 0;
- * }
- * ```
- *
- * In this function we intended guard against a failure of
- * `s2n_answer_to_the_ultimate_question` but that function doesn't
- * actually return an error signal. Again, this can lead to sublte
- * bugs.
- *
- * ## Ignored error signals
- *
- * Without the `warn_unused_result` function attribute, the compiler
- * provides no warning when forgetting to `GUARD` a function. Missing
- * a `GUARD` can lead to subtle bugs.
- *
- * ```c
- * int s2n_answer_to_the_ultimate_question() {
- * s2n_sleep_for_years(7500000); // <- THIS SHOULD BE GUARDED!!!
- * return 42;
- * }
- * ```
- *
- * # Solution
- *
- * s2n_result provides a newtype declaration, which is popular in
- * languages like [Haskell](https://wiki.haskell.org/Newtype) and
- * [Rust](https://doc.rust-lang.org/rust-by-example/generics/new_types.html).
- *
- * Functions that return S2N_RESULT are automatically marked with the
- * `warn_unused_result` attribute, which ensures they are GUARDed.
- */
-
-#include <s2n.h>
-#include <stdbool.h>
-#include "utils/s2n_result.h"
-
-/* returns true when the result is S2N_RESULT_OK */
-inline bool s2n_result_is_ok(s2n_result result)
-{
- return result.__error_signal == S2N_SUCCESS;
-}
-
-/* returns true when the result is S2N_RESULT_ERROR */
-inline bool s2n_result_is_error(s2n_result result)
-{
- return result.__error_signal == S2N_FAILURE;
-}
+/*
+ * 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.
+ */
+
+/*
+ * The goal of s2n_result is to provide a strongly-typed error
+ * signal value, which provides the compiler with enough information
+ * to catch bugs.
+ *
+ * Historically, s2n has used int to signal errors. This has caused a few issues:
+ *
+ * ## GUARD in a function returning integer types
+ *
+ * There is no compiler error if `GUARD(nested_call());` is used in a function
+ * that is meant to return integer type - not a error signal.
+ *
+ * ```c
+ * uint8_t s2n_answer_to_the_ultimate_question() {
+ * GUARD(s2n_sleep_for_years(7500000));
+ * return 42;
+ * }
+ * ```
+ *
+ * In this function we intended to return a `uint8_t` but used a
+ * `GUARD` which will return -1 if the call fails. This can lead to
+ * very subtle bugs.
+ *
+ * ## `GUARD`ing a function returning any integer type
+ *
+ * There is no compiler error if `GUARD(nested_call());` is used
+ * on a function that doesn't actually return an error signal
+ *
+ * ```c
+ * int s2n_deep_thought() {
+ * GUARD(s2n_answer_to_the_ultimate_question());
+ * return 0;
+ * }
+ * ```
+ *
+ * In this function we intended guard against a failure of
+ * `s2n_answer_to_the_ultimate_question` but that function doesn't
+ * actually return an error signal. Again, this can lead to sublte
+ * bugs.
+ *
+ * ## Ignored error signals
+ *
+ * Without the `warn_unused_result` function attribute, the compiler
+ * provides no warning when forgetting to `GUARD` a function. Missing
+ * a `GUARD` can lead to subtle bugs.
+ *
+ * ```c
+ * int s2n_answer_to_the_ultimate_question() {
+ * s2n_sleep_for_years(7500000); // <- THIS SHOULD BE GUARDED!!!
+ * return 42;
+ * }
+ * ```
+ *
+ * # Solution
+ *
+ * s2n_result provides a newtype declaration, which is popular in
+ * languages like [Haskell](https://wiki.haskell.org/Newtype) and
+ * [Rust](https://doc.rust-lang.org/rust-by-example/generics/new_types.html).
+ *
+ * Functions that return S2N_RESULT are automatically marked with the
+ * `warn_unused_result` attribute, which ensures they are GUARDed.
+ */
+
+#include <s2n.h>
+#include <stdbool.h>
+#include "utils/s2n_result.h"
+
+/* returns true when the result is S2N_RESULT_OK */
+inline bool s2n_result_is_ok(s2n_result result)
+{
+ return result.__error_signal == S2N_SUCCESS;
+}
+
+/* returns true when the result is S2N_RESULT_ERROR */
+inline bool s2n_result_is_error(s2n_result result)
+{
+ return result.__error_signal == S2N_FAILURE;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_result.h b/contrib/restricted/aws/s2n/utils/s2n_result.h
index 9a1b3ed13a..a0e38a8468 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_result.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_result.h
@@ -1,48 +1,48 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <s2n.h>
-#include <stdbool.h>
-
-/* A value which indicates the outcome of a function */
-typedef struct {
- int __error_signal;
-} s2n_result;
-
-/* used to signal a successful function return */
-#define S2N_RESULT_OK ((s2n_result) { S2N_SUCCESS })
-
-/* used to signal an error while executing a function */
-#define S2N_RESULT_ERROR ((s2n_result) { S2N_FAILURE })
-
-#if defined(__clang__) || defined(__GNUC__)
-#define S2N_RESULT_MUST_USE __attribute__((warn_unused_result))
-#else
-#define S2N_RESULT_MUST_USE
-#endif
-
-/* returns true when the result is S2N_RESULT_OK */
-S2N_RESULT_MUST_USE bool s2n_result_is_ok(s2n_result result);
-
-/* returns true when the result is S2N_RESULT_ERROR */
-S2N_RESULT_MUST_USE bool s2n_result_is_error(s2n_result result);
-
-/* used in function declarations to signal function fallibility */
-#define S2N_RESULT S2N_RESULT_MUST_USE s2n_result
-
-/* converts the S2N_RESULT into posix error codes */
-#define S2N_RESULT_TO_POSIX( x ) (s2n_result_is_ok(x) ? S2N_SUCCESS : S2N_FAILURE)
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <s2n.h>
+#include <stdbool.h>
+
+/* A value which indicates the outcome of a function */
+typedef struct {
+ int __error_signal;
+} s2n_result;
+
+/* used to signal a successful function return */
+#define S2N_RESULT_OK ((s2n_result) { S2N_SUCCESS })
+
+/* used to signal an error while executing a function */
+#define S2N_RESULT_ERROR ((s2n_result) { S2N_FAILURE })
+
+#if defined(__clang__) || defined(__GNUC__)
+#define S2N_RESULT_MUST_USE __attribute__((warn_unused_result))
+#else
+#define S2N_RESULT_MUST_USE
+#endif
+
+/* returns true when the result is S2N_RESULT_OK */
+S2N_RESULT_MUST_USE bool s2n_result_is_ok(s2n_result result);
+
+/* returns true when the result is S2N_RESULT_ERROR */
+S2N_RESULT_MUST_USE bool s2n_result_is_error(s2n_result result);
+
+/* used in function declarations to signal function fallibility */
+#define S2N_RESULT S2N_RESULT_MUST_USE s2n_result
+
+/* converts the S2N_RESULT into posix error codes */
+#define S2N_RESULT_TO_POSIX( x ) (s2n_result_is_ok(x) ? S2N_SUCCESS : S2N_FAILURE)
diff --git a/contrib/restricted/aws/s2n/utils/s2n_rfc5952.c b/contrib/restricted/aws/s2n/utils/s2n_rfc5952.c
index cab0464a6f..4640fe72fc 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_rfc5952.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_rfc5952.c
@@ -1,135 +1,135 @@
-/*
- * 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/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-
-#include <error/s2n_errno.h>
-
-#include "utils/s2n_rfc5952.h"
-#include "utils/s2n_safety.h"
-
-static uint8_t dec[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
-static uint8_t hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
-S2N_RESULT s2n_inet_ntop(int af, const void *addr, struct s2n_blob *dst)
-{
- const uint8_t *bytes = addr;
- uint8_t *cursor = dst->data;
-
- if (af == AF_INET) {
- ENSURE(dst->size >= sizeof("111.222.333.444"), S2N_ERR_SIZE_MISMATCH);
-
- for (int i = 0; i < 4; i++) {
- if (bytes[i] / 100) {
- *cursor++ = dec[bytes[i] / 100];
- }
- if (bytes[i] >= 10) {
- *cursor++ = dec[(bytes[i] % 100) / 10];
- }
- *cursor++ = dec[(bytes[i] % 10)];
- *cursor++ = '.';
- }
-
- *--cursor = '\0';
-
- return S2N_RESULT_OK;
- }
-
- if (af == AF_INET6) {
- ENSURE(dst->size >= sizeof("1111:2222:3333:4444:5555:6666:7777:8888"), S2N_ERR_SIZE_MISMATCH);
-
- /* See Section 4 of RFC5952 for the rules we are going to follow here
- *
- * Here's the general algorithm:
- *
- * 1/ Treat the bytes as 8 16-bit fields
- * 2/ Find the longest run of 16-bit fields.
- * 3/ or if there are two or more equal length longest runs, go with the left-most run
- * 4/ Make that run ::
- * 5/ Print the remaining 16-bit fields in lowercase hex, no leading zeroes
- */
-
- uint16_t octets[8] = { 0 };
-
- int longest_run_start = 0;
- int longest_run_length = 0;
- int current_run_length = 0;
-
- /* 2001:db8::1:0:0:1 */
-
- /* Find the longest run of zeroes */
- for (int i = 0; i < 8; i++) {
- octets[i] = (bytes[i * 2] << 8) + bytes[(i * 2) + 1];
-
- if (octets[i]) {
- current_run_length = 0;
- }
- else {
- current_run_length++;
- }
-
- if (current_run_length > longest_run_length) {
- longest_run_length = current_run_length;
- longest_run_start = (i - current_run_length) + 1;
- }
- }
-
-
- for (int i = 0; i < 8; i++) {
- if (i == longest_run_start && longest_run_length > 1) {
-
- if (i == 0) {
- *cursor++ = ':';
- }
-
- if (longest_run_length == 8) {
- *cursor++ = ':';
- }
-
- i += longest_run_length - 1;
-
- }
- else {
- uint8_t nibbles[4] = { (octets[i] & 0xF000) >> 12,
- (octets[i] & 0x0F00) >> 8,
- (octets[i] & 0x00F0) >> 4,
- (octets[i] & 0x000F) };
-
- /* Skip up to three leading zeroes */
- int j;
- for (j = 0; j < 3; j++) {
- if (nibbles[j]) {
- break;
- }
- }
-
- for (; j < 4; j++) {
- *cursor++ = hex[ nibbles[j] ];
- }
-
- }
-
- *cursor++ = ':';
- }
-
- *--cursor = '\0';
-
- return S2N_RESULT_OK;
- }
-
- BAIL(S2N_ERR_INVALID_ARGUMENT);
-}
+/*
+ * 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/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+
+#include <error/s2n_errno.h>
+
+#include "utils/s2n_rfc5952.h"
+#include "utils/s2n_safety.h"
+
+static uint8_t dec[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+static uint8_t hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+S2N_RESULT s2n_inet_ntop(int af, const void *addr, struct s2n_blob *dst)
+{
+ const uint8_t *bytes = addr;
+ uint8_t *cursor = dst->data;
+
+ if (af == AF_INET) {
+ ENSURE(dst->size >= sizeof("111.222.333.444"), S2N_ERR_SIZE_MISMATCH);
+
+ for (int i = 0; i < 4; i++) {
+ if (bytes[i] / 100) {
+ *cursor++ = dec[bytes[i] / 100];
+ }
+ if (bytes[i] >= 10) {
+ *cursor++ = dec[(bytes[i] % 100) / 10];
+ }
+ *cursor++ = dec[(bytes[i] % 10)];
+ *cursor++ = '.';
+ }
+
+ *--cursor = '\0';
+
+ return S2N_RESULT_OK;
+ }
+
+ if (af == AF_INET6) {
+ ENSURE(dst->size >= sizeof("1111:2222:3333:4444:5555:6666:7777:8888"), S2N_ERR_SIZE_MISMATCH);
+
+ /* See Section 4 of RFC5952 for the rules we are going to follow here
+ *
+ * Here's the general algorithm:
+ *
+ * 1/ Treat the bytes as 8 16-bit fields
+ * 2/ Find the longest run of 16-bit fields.
+ * 3/ or if there are two or more equal length longest runs, go with the left-most run
+ * 4/ Make that run ::
+ * 5/ Print the remaining 16-bit fields in lowercase hex, no leading zeroes
+ */
+
+ uint16_t octets[8] = { 0 };
+
+ int longest_run_start = 0;
+ int longest_run_length = 0;
+ int current_run_length = 0;
+
+ /* 2001:db8::1:0:0:1 */
+
+ /* Find the longest run of zeroes */
+ for (int i = 0; i < 8; i++) {
+ octets[i] = (bytes[i * 2] << 8) + bytes[(i * 2) + 1];
+
+ if (octets[i]) {
+ current_run_length = 0;
+ }
+ else {
+ current_run_length++;
+ }
+
+ if (current_run_length > longest_run_length) {
+ longest_run_length = current_run_length;
+ longest_run_start = (i - current_run_length) + 1;
+ }
+ }
+
+
+ for (int i = 0; i < 8; i++) {
+ if (i == longest_run_start && longest_run_length > 1) {
+
+ if (i == 0) {
+ *cursor++ = ':';
+ }
+
+ if (longest_run_length == 8) {
+ *cursor++ = ':';
+ }
+
+ i += longest_run_length - 1;
+
+ }
+ else {
+ uint8_t nibbles[4] = { (octets[i] & 0xF000) >> 12,
+ (octets[i] & 0x0F00) >> 8,
+ (octets[i] & 0x00F0) >> 4,
+ (octets[i] & 0x000F) };
+
+ /* Skip up to three leading zeroes */
+ int j;
+ for (j = 0; j < 3; j++) {
+ if (nibbles[j]) {
+ break;
+ }
+ }
+
+ for (; j < 4; j++) {
+ *cursor++ = hex[ nibbles[j] ];
+ }
+
+ }
+
+ *cursor++ = ':';
+ }
+
+ *--cursor = '\0';
+
+ return S2N_RESULT_OK;
+ }
+
+ BAIL(S2N_ERR_INVALID_ARGUMENT);
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_rfc5952.h b/contrib/restricted/aws/s2n/utils/s2n_rfc5952.h
index 724c923128..bc0681afb7 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_rfc5952.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_rfc5952.h
@@ -1,24 +1,24 @@
-#pragma once
-/*
- * 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
- */
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-/**
- * Converts a binary representation of an ip address into its canonical string
- * representation. Returns 0 on success and -1 on failure.
- */
-extern S2N_RESULT s2n_inet_ntop(int af, const void *addr, struct s2n_blob *dst);
-
+#pragma once
+/*
+ * 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
+ */
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+/**
+ * Converts a binary representation of an ip address into its canonical string
+ * representation. Returns 0 on success and -1 on failure.
+ */
+extern S2N_RESULT s2n_inet_ntop(int af, const void *addr, struct s2n_blob *dst);
+
diff --git a/contrib/restricted/aws/s2n/utils/s2n_safety.c b/contrib/restricted/aws/s2n/utils/s2n_safety.c
index d786c4d852..87fb1059d1 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_safety.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_safety.c
@@ -1,234 +1,234 @@
-/*
- * 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.
- */
-
-#define _GNU_SOURCE /* For syscall on Linux */
-#undef _POSIX_C_SOURCE /* For syscall() on Mac OS X */
-
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "utils/s2n_annotations.h"
-#include "utils/s2n_safety.h"
-
-/**
- * Get the process id
- *
- * Returns:
- * The process ID of the current process
- */
-pid_t s2n_actual_getpid()
-{
-#if defined(__GNUC__) && defined(SYS_getpid)
- /* http://yarchive.net/comp/linux/getpid_caching.html */
- return (pid_t) syscall(SYS_getpid);
-#else
- return getpid();
-#endif
-}
-
-/**
- * Given arrays "a" and "b" of length "len", determine whether they
- * hold equal contents.
- *
- * The execution time of this function is independent of the values
- * stored in the arrays.
- *
- * Timing may depend on the length of the arrays, and on the location
- * of the arrays in memory (e.g. if a buffer has been paged out, this
- * will affect the timing of this function).
- *
- * Returns:
- * Whether all bytes in arrays "a" and "b" are identical
- */
-bool s2n_constant_time_equals(const uint8_t * a, const uint8_t * b, const uint32_t len)
-{
- S2N_PUBLIC_INPUT(a);
- S2N_PUBLIC_INPUT(b);
- S2N_PUBLIC_INPUT(len);
-
- if (len != 0 && (a == NULL || b == NULL)) {
- return false;
- }
-
- uint8_t xor = 0;
- for (int i = 0; i < len; i++) {
- /* Invariants must hold for each execution of the loop
- * and at loop exit, hence the <= */
- S2N_INVARIENT(i <= len);
- xor |= a[i] ^ b[i];
- }
-
- return !xor;
-}
-
-/**
- * Given arrays "dest" and "src" of length "len", conditionally copy "src" to "dest"
- * The execution time of this function is independent of the values
- * stored in the arrays, and of whether the copy occurs.
- *
- * Timing may depend on the length of the arrays, and on the location
- * of the arrays in memory (e.g. if a buffer has been paged out, this
- * will affect the timing of this function).
- *
- */
-int s2n_constant_time_copy_or_dont(uint8_t * dest, const uint8_t * src, uint32_t len, uint8_t dont)
-{
- S2N_PUBLIC_INPUT(dest);
- S2N_PUBLIC_INPUT(src);
- S2N_PUBLIC_INPUT(len);
-
-/* This underflows a value of 0 to the maximum value via arithmetic underflow,
- * so the check for arithmetic overflow/underflow needs to be disabled for CBMC.
- * Additionally, uint_fast16_t is defined as the fastest available unsigned
- * integer with 16 bits or greater, and is not guaranteed to be 16 bits long.
- * To handle this, the conversion overflow check also needs to be enabled. */
-#pragma CPROVER check push
-#pragma CPROVER check disable "conversion"
-#pragma CPROVER check disable "unsigned-overflow"
- uint8_t mask = ((uint_fast16_t)((uint_fast16_t)(dont) - 1)) >> 8;
-#pragma CPROVER check pop
-
- /* dont = 0 : mask = 0xff */
- /* dont > 0 : mask = 0x00 */
-
- for (uint32_t i = 0; i < len; i++) {
- uint8_t old = dest[i];
- uint8_t diff = (old ^ src[i]) & mask;
- dest[i] = old ^ diff;
- }
-
- return 0;
-}
-
-/* If src contains valid PKCS#1 v1.5 padding of exactly expectlen bytes, decode
- * it into dst, otherwise leave dst alone. Execution time is independent of the
- * content of src, but may depend on srclen/expectlen.
- *
- * Normally, one would fill dst with random bytes before calling this function.
- */
-int s2n_constant_time_pkcs1_unpad_or_dont(uint8_t * dst, const uint8_t * src, uint32_t srclen, uint32_t expectlen)
-{
- S2N_PUBLIC_INPUT(dst);
- S2N_PUBLIC_INPUT(src);
- S2N_PUBLIC_INPUT(srclen);
- S2N_PUBLIC_INPUT(expectlen);
-
- /* Before doing anything else, some basic sanity checks on input lengths */
- if (srclen < expectlen + 3) {
- /* Not enough room for PKCS#1v1.5 padding, so treat it as bad padding */
- return 0;
- }
-
- /* First, determine (in constant time) whether the padding is valid.
- * If the padding is valid we expect that:
- * Bytes 0 and 1 will equal 0x00 and 0x02
- * Bytes (srclen-expectlen-1) will be zero
- * Bytes 2 through (srclen-expectlen-1) will be nonzero
- */
- uint8_t dont_copy = 0;
- const uint8_t *start_of_data = src + srclen - expectlen;
-
- dont_copy |= src[0] ^ 0x00;
- dont_copy |= src[1] ^ 0x02;
-
-/* Since -1 is being used, we need to disable the pointer overflow check for CBMC. */
-#pragma CPROVER check push
-#pragma CPROVER check disable "pointer-overflow"
- dont_copy |= start_of_data[-1] ^ 0x00;
-#pragma CPROVER check pop
-
-/* This underflows a value of 0 to the maximum value via arithmetic underflow,
- * so the check for arithmetic overflow/underflow needs to be disabled for CBMC.
- * Additionally, uint_fast16_t is defined as the fastest available unsigned
- * integer with 16 bits or greater, and is not guaranteed to be 16 bits long.
- * To handle this, the conversion overflow check also needs to be enabled. */
-#pragma CPROVER check push
-#pragma CPROVER check disable "conversion"
-#pragma CPROVER check disable "unsigned-overflow"
- for (uint32_t i = 2; i < srclen - expectlen - 1; i++) {
- /* Note! We avoid using logical NOT (!) here; while in practice
- * many compilers will use constant-time sequences for this operator,
- * at least on x86 (e.g. cmp -> setcc, or vectorized pcmpeq), this is
- * not guaranteed to hold, and some architectures might not have a
- * convenient mechanism for generating a branchless logical not. */
- uint8_t mask = ((uint_fast16_t)((uint_fast16_t)(src[i]) - 1)) >> 8;
- /* src[i] = 0 : mask = 0xff */
- /* src[i] > 0 : mask = 0x00 */
- dont_copy |= mask;
- }
-#pragma CPROVER check pop
-
- s2n_constant_time_copy_or_dont(dst, start_of_data, expectlen, dont_copy);
-
- return 0;
-}
-
-static bool s_s2n_in_unit_test = false;
-
-bool s2n_in_unit_test()
-{
- return s_s2n_in_unit_test;
-}
-
-int s2n_in_unit_test_set(bool newval)
-{
- s_s2n_in_unit_test = newval;
- return S2N_SUCCESS;
-}
-
-int s2n_align_to(uint32_t initial, uint32_t alignment, uint32_t* out)
-{
- notnull_check(out);
- ENSURE_POSIX(alignment != 0, S2N_ERR_SAFETY);
- if (initial == 0) {
- *out = 0;
- return S2N_SUCCESS;
- }
- const uint64_t i = initial;
- const uint64_t a = alignment;
- const uint64_t result = a * (((i - 1) / a) + 1);
- S2N_ERROR_IF(result > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
- *out = (uint32_t) result;
- return S2N_SUCCESS;
-}
-
-int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out)
-{
- notnull_check(out);
- const uint64_t result = ((uint64_t) a) * ((uint64_t) b);
- S2N_ERROR_IF(result > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
- *out = (uint32_t) result;
- return S2N_SUCCESS;
-}
-
-int s2n_add_overflow(uint32_t a, uint32_t b, uint32_t* out)
-{
- notnull_check(out);
- uint64_t result = ((uint64_t) a) + ((uint64_t) b);
- S2N_ERROR_IF(result > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
- *out = (uint32_t) result;
- return S2N_SUCCESS;
-}
-
-int s2n_sub_overflow(uint32_t a, uint32_t b, uint32_t* out)
-{
- notnull_check(out);
- S2N_ERROR_IF(a < b, S2N_ERR_INTEGER_OVERFLOW);
- *out = a - b;
- return S2N_SUCCESS;
-}
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE /* For syscall on Linux */
+#undef _POSIX_C_SOURCE /* For syscall() on Mac OS X */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "utils/s2n_annotations.h"
+#include "utils/s2n_safety.h"
+
+/**
+ * Get the process id
+ *
+ * Returns:
+ * The process ID of the current process
+ */
+pid_t s2n_actual_getpid()
+{
+#if defined(__GNUC__) && defined(SYS_getpid)
+ /* http://yarchive.net/comp/linux/getpid_caching.html */
+ return (pid_t) syscall(SYS_getpid);
+#else
+ return getpid();
+#endif
+}
+
+/**
+ * Given arrays "a" and "b" of length "len", determine whether they
+ * hold equal contents.
+ *
+ * The execution time of this function is independent of the values
+ * stored in the arrays.
+ *
+ * Timing may depend on the length of the arrays, and on the location
+ * of the arrays in memory (e.g. if a buffer has been paged out, this
+ * will affect the timing of this function).
+ *
+ * Returns:
+ * Whether all bytes in arrays "a" and "b" are identical
+ */
+bool s2n_constant_time_equals(const uint8_t * a, const uint8_t * b, const uint32_t len)
+{
+ S2N_PUBLIC_INPUT(a);
+ S2N_PUBLIC_INPUT(b);
+ S2N_PUBLIC_INPUT(len);
+
+ if (len != 0 && (a == NULL || b == NULL)) {
+ return false;
+ }
+
+ uint8_t xor = 0;
+ for (int i = 0; i < len; i++) {
+ /* Invariants must hold for each execution of the loop
+ * and at loop exit, hence the <= */
+ S2N_INVARIENT(i <= len);
+ xor |= a[i] ^ b[i];
+ }
+
+ return !xor;
+}
+
+/**
+ * Given arrays "dest" and "src" of length "len", conditionally copy "src" to "dest"
+ * The execution time of this function is independent of the values
+ * stored in the arrays, and of whether the copy occurs.
+ *
+ * Timing may depend on the length of the arrays, and on the location
+ * of the arrays in memory (e.g. if a buffer has been paged out, this
+ * will affect the timing of this function).
+ *
+ */
+int s2n_constant_time_copy_or_dont(uint8_t * dest, const uint8_t * src, uint32_t len, uint8_t dont)
+{
+ S2N_PUBLIC_INPUT(dest);
+ S2N_PUBLIC_INPUT(src);
+ S2N_PUBLIC_INPUT(len);
+
+/* This underflows a value of 0 to the maximum value via arithmetic underflow,
+ * so the check for arithmetic overflow/underflow needs to be disabled for CBMC.
+ * Additionally, uint_fast16_t is defined as the fastest available unsigned
+ * integer with 16 bits or greater, and is not guaranteed to be 16 bits long.
+ * To handle this, the conversion overflow check also needs to be enabled. */
+#pragma CPROVER check push
+#pragma CPROVER check disable "conversion"
+#pragma CPROVER check disable "unsigned-overflow"
+ uint8_t mask = ((uint_fast16_t)((uint_fast16_t)(dont) - 1)) >> 8;
+#pragma CPROVER check pop
+
+ /* dont = 0 : mask = 0xff */
+ /* dont > 0 : mask = 0x00 */
+
+ for (uint32_t i = 0; i < len; i++) {
+ uint8_t old = dest[i];
+ uint8_t diff = (old ^ src[i]) & mask;
+ dest[i] = old ^ diff;
+ }
+
+ return 0;
+}
+
+/* If src contains valid PKCS#1 v1.5 padding of exactly expectlen bytes, decode
+ * it into dst, otherwise leave dst alone. Execution time is independent of the
+ * content of src, but may depend on srclen/expectlen.
+ *
+ * Normally, one would fill dst with random bytes before calling this function.
+ */
+int s2n_constant_time_pkcs1_unpad_or_dont(uint8_t * dst, const uint8_t * src, uint32_t srclen, uint32_t expectlen)
+{
+ S2N_PUBLIC_INPUT(dst);
+ S2N_PUBLIC_INPUT(src);
+ S2N_PUBLIC_INPUT(srclen);
+ S2N_PUBLIC_INPUT(expectlen);
+
+ /* Before doing anything else, some basic sanity checks on input lengths */
+ if (srclen < expectlen + 3) {
+ /* Not enough room for PKCS#1v1.5 padding, so treat it as bad padding */
+ return 0;
+ }
+
+ /* First, determine (in constant time) whether the padding is valid.
+ * If the padding is valid we expect that:
+ * Bytes 0 and 1 will equal 0x00 and 0x02
+ * Bytes (srclen-expectlen-1) will be zero
+ * Bytes 2 through (srclen-expectlen-1) will be nonzero
+ */
+ uint8_t dont_copy = 0;
+ const uint8_t *start_of_data = src + srclen - expectlen;
+
+ dont_copy |= src[0] ^ 0x00;
+ dont_copy |= src[1] ^ 0x02;
+
+/* Since -1 is being used, we need to disable the pointer overflow check for CBMC. */
+#pragma CPROVER check push
+#pragma CPROVER check disable "pointer-overflow"
+ dont_copy |= start_of_data[-1] ^ 0x00;
+#pragma CPROVER check pop
+
+/* This underflows a value of 0 to the maximum value via arithmetic underflow,
+ * so the check for arithmetic overflow/underflow needs to be disabled for CBMC.
+ * Additionally, uint_fast16_t is defined as the fastest available unsigned
+ * integer with 16 bits or greater, and is not guaranteed to be 16 bits long.
+ * To handle this, the conversion overflow check also needs to be enabled. */
+#pragma CPROVER check push
+#pragma CPROVER check disable "conversion"
+#pragma CPROVER check disable "unsigned-overflow"
+ for (uint32_t i = 2; i < srclen - expectlen - 1; i++) {
+ /* Note! We avoid using logical NOT (!) here; while in practice
+ * many compilers will use constant-time sequences for this operator,
+ * at least on x86 (e.g. cmp -> setcc, or vectorized pcmpeq), this is
+ * not guaranteed to hold, and some architectures might not have a
+ * convenient mechanism for generating a branchless logical not. */
+ uint8_t mask = ((uint_fast16_t)((uint_fast16_t)(src[i]) - 1)) >> 8;
+ /* src[i] = 0 : mask = 0xff */
+ /* src[i] > 0 : mask = 0x00 */
+ dont_copy |= mask;
+ }
+#pragma CPROVER check pop
+
+ s2n_constant_time_copy_or_dont(dst, start_of_data, expectlen, dont_copy);
+
+ return 0;
+}
+
+static bool s_s2n_in_unit_test = false;
+
+bool s2n_in_unit_test()
+{
+ return s_s2n_in_unit_test;
+}
+
+int s2n_in_unit_test_set(bool newval)
+{
+ s_s2n_in_unit_test = newval;
+ return S2N_SUCCESS;
+}
+
+int s2n_align_to(uint32_t initial, uint32_t alignment, uint32_t* out)
+{
+ notnull_check(out);
+ ENSURE_POSIX(alignment != 0, S2N_ERR_SAFETY);
+ if (initial == 0) {
+ *out = 0;
+ return S2N_SUCCESS;
+ }
+ const uint64_t i = initial;
+ const uint64_t a = alignment;
+ const uint64_t result = a * (((i - 1) / a) + 1);
+ S2N_ERROR_IF(result > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ *out = (uint32_t) result;
+ return S2N_SUCCESS;
+}
+
+int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out)
+{
+ notnull_check(out);
+ const uint64_t result = ((uint64_t) a) * ((uint64_t) b);
+ S2N_ERROR_IF(result > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ *out = (uint32_t) result;
+ return S2N_SUCCESS;
+}
+
+int s2n_add_overflow(uint32_t a, uint32_t b, uint32_t* out)
+{
+ notnull_check(out);
+ uint64_t result = ((uint64_t) a) + ((uint64_t) b);
+ S2N_ERROR_IF(result > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ *out = (uint32_t) result;
+ return S2N_SUCCESS;
+}
+
+int s2n_sub_overflow(uint32_t a, uint32_t b, uint32_t* out)
+{
+ notnull_check(out);
+ S2N_ERROR_IF(a < b, S2N_ERR_INTEGER_OVERFLOW);
+ *out = a - b;
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_safety.h b/contrib/restricted/aws/s2n/utils/s2n_safety.h
index 67a0328901..5dbc505d47 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_safety.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_safety.h
@@ -1,408 +1,408 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <string.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include "error/s2n_errno.h"
-#include "utils/s2n_ensure.h"
-#include "utils/s2n_result.h"
-
-/* Success signal value for OpenSSL functions */
-#define _OSSL_SUCCESS 1
-
-/**
- * The goal of s2n_safety is to provide helpers to perform common
- * checks, which help with code readability.
- */
-
-/**
- * Sets the global `errno` and returns with a `S2N_RESULT_ERROR`
- */
-#define BAIL( x ) do { _S2N_ERROR( ( x ) ); return S2N_RESULT_ERROR; } while (0)
-
-/**
- * Sets the global `errno` and returns with a POSIX error (`-1`)
- */
-#define BAIL_POSIX( x ) do { _S2N_ERROR( ( x ) ); return S2N_FAILURE; } while (0)
-
-/**
- * Sets the global `errno` and returns with a `NULL` pointer value
- */
-#define BAIL_PTR( x ) do { _S2N_ERROR( ( x ) ); return NULL; } while (0)
-
-/**
- * Ensures the `condition` is `true`, otherwise the function will `BAIL` with an `error`
- */
-#define ENSURE( condition , error ) __S2N_ENSURE((condition), BAIL(error))
-
-/**
- * Ensures the `result` is OK, otherwise the function will `BAIL` with an `error`
- */
-#define ENSURE_OK( result , error ) __S2N_ENSURE(s2n_result_is_ok(result), BAIL(error))
-
-/**
- * Ensures `n` is greater than or equal to `min`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
- */
-#define ENSURE_GTE( n , min ) ENSURE((n) >= (min), S2N_ERR_SAFETY)
-
-/**
- * Ensures `n` is less than or equal to `max`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
- */
-#define ENSURE_LTE( n , max ) ENSURE((n) <= (max), S2N_ERR_SAFETY)
-
-/**
- * Ensures `n` is greater than `min`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
- */
-#define ENSURE_GT( n , min ) ENSURE((n) > (min), S2N_ERR_SAFETY)
-
-/**
- * Ensures `n` is less than `min`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
- */
-#define ENSURE_LT( n , max ) ENSURE((n) < (max), S2N_ERR_SAFETY)
-
-/**
- * Ensures `a` is equal to `b`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
- */
-#define ENSURE_EQ( a , b ) ENSURE((a) == (b), S2N_ERR_SAFETY)
-
-/**
- * Ensures `a` is not equal to `b`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
- */
-#define ENSURE_NE( a , b ) ENSURE((a) != (b), S2N_ERR_SAFETY)
-
-/**
- * Ensures the `condition` is `true`, otherwise the function will `BAIL_POSIX` with an `error`
- */
-#define ENSURE_POSIX( condition , error ) __S2N_ENSURE((condition), BAIL_POSIX(error))
-
-/**
- * Ensures the `condition` is `true`, otherwise the function will `BAIL_PTR` with an `error`
- */
-#define ENSURE_PTR( condition , error ) __S2N_ENSURE((condition), BAIL_PTR(error))
-
-/**
- * Ensures `x` is not `NULL`, otherwise the function will `BAIL_PTR` with an `error`
- */
-#define ENSURE_REF_PTR( x ) ENSURE_PTR(S2N_OBJECT_PTR_IS_READABLE(x), S2N_ERR_NULL)
-
-/**
- * Ensures `x` is a readable reference, otherwise the function will `BAIL` with `S2N_ERR_NULL`
- */
-#define ENSURE_REF( x ) ENSURE(S2N_OBJECT_PTR_IS_READABLE(x), S2N_ERR_NULL)
-
-/**
- * Ensures `x` is a readable reference, otherwise the function will `BAIL_POSIX` with `S2N_ERR_NULL`
- */
-#define ENSURE_POSIX_REF( x ) ENSURE_POSIX(S2N_OBJECT_PTR_IS_READABLE(x), S2N_ERR_NULL)
-
-/**
- * Ensures `x` is a mutable reference, otherwise the function will `BAIL` with `S2N_ERR_NULL`
- */
-#define ENSURE_MUT( x ) ENSURE(S2N_OBJECT_PTR_IS_WRITABLE(x), S2N_ERR_NULL)
-
-/**
- * Ensures `x` is a mutable reference, otherwise the function will `BAIL_POSIX` with `S2N_ERR_NULL`
- */
-#define ENSURE_POSIX_MUT( x ) ENSURE_POSIX(S2N_OBJECT_PTR_IS_WRITABLE(x), S2N_ERR_NULL)
-
-/**
- * Ensures `min <= n <= max`
- */
-#define ENSURE_INCLUSIVE_RANGE( min , n , max ) \
- do { \
- __typeof( n ) __tmp_n = ( n ); \
- ENSURE_GTE(__tmp_n, min); \
- ENSURE_LTE(__tmp_n, max); \
- } while(0)
-
-/**
- * Ensures `min < n < max`
- */
-#define ENSURE_EXCLUSIVE_RANGE( min , n , max ) \
- do { \
- __typeof( n ) __tmp_n = ( n ); \
- ENSURE_GT(__tmp_n, min); \
- ENSURE_LT(__tmp_n, max); \
- } while(0)
-
-/**
- * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
- */
-#define PRECONDITION( result ) GUARD_RESULT(__S2N_ENSURE_PRECONDITION(result))
-
-/**
- * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
- */
-#define POSTCONDITION( result ) GUARD_RESULT(__S2N_ENSURE_POSTCONDITION(result))
-
-/**
- * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
- */
-#define PRECONDITION_POSIX( result ) GUARD_AS_POSIX(__S2N_ENSURE_PRECONDITION(result))
-
-/**
- * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
- */
-#define POSTCONDITION_POSIX( result ) GUARD_AS_POSIX(__S2N_ENSURE_POSTCONDITION(result))
-
-/**
- * Ensures the `condition` is `true`, otherwise the function will `BAIL` with an `error`.
- * When the code is built in debug mode, they are checked.
- * When the code is built in production mode, they are ignored.
- */
-#define DEBUG_ENSURE( condition, error ) __S2N_ENSURE_DEBUG((condition), BAIL(error))
-
-/**
- * Ensures the `condition` is `true`, otherwise the function will `BAIL_POSIX` with an `error`.
- * When the code is built in debug mode, they are checked.
- * When the code is built in production mode, they are ignored.
- */
-#define DEBUG_ENSURE_POSIX( condition, error ) __S2N_ENSURE_DEBUG((condition), BAIL_POSIX(error))
-
-/**
- * Ensures `x` is not an error, otherwise the function will return an error signal
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD( x ) GUARD_POSIX(x)
-
-/**
- * Ensures `x` is not an error, otherwise goto `label`
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD_GOTO( x , label ) GUARD_POSIX_GOTO((x), (label))
-
-/**
- * Ensures `x` is not an error, otherwise the function will return `NULL`
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD_PTR( x ) GUARD_POSIX_PTR(x)
-
-/**
- * Ensures `x` is not `NULL`, otherwise the function will return an error signal
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD_NONNULL( x ) GUARD_POSIX_NONNULL(x)
-
-/**
- * Ensures `x` is not `NULL`, otherwise goto `label`
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD_NONNULL_GOTO( x , label ) __S2N_ENSURE((x) != NULL, goto label)
-
-/**
- * Ensures `x` is not `NULL`, otherwise the function will return `NULL`
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD_NONNULL_PTR( x ) __S2N_ENSURE((x) != NULL, return NULL)
-
-/**
- * Ensures `x` is not a OpenSSL error, otherwise the function will return an error signal
- *
- * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
- */
-#define GUARD_OSSL( x, error ) GUARD_POSIX_OSSL((x), (error))
-
-/**
- * Ensures `x` is ok, otherwise the function will return an `S2N_RESULT_ERROR`
- */
-#define GUARD_RESULT( x ) __S2N_ENSURE(s2n_result_is_ok(x), return S2N_RESULT_ERROR)
-
-/**
- * Ensures `x` is ok, otherwise goto `label`
- */
-#define GUARD_RESULT_GOTO( x, label ) __S2N_ENSURE(s2n_result_is_ok(x), goto label)
-
-/**
- * Ensures `x` is ok, otherwise the function will return `NULL`
- */
-#define GUARD_RESULT_PTR( x ) __S2N_ENSURE(s2n_result_is_ok(x), return NULL)
-
-/**
- * Ensures `x` is not `NULL`, otherwise the function will return an `S2N_RESULT_ERROR`
- */
-#define GUARD_RESULT_NONNULL( x ) __S2N_ENSURE((x) != NULL, return S2N_RESULT_ERROR)
-
-/**
- * Ensures `x` is not a OpenSSL error, otherwise the function will `BAIL` with `error`
- */
-/* TODO: use the OSSL error code in error reporting https://github.com/awslabs/s2n/issues/705 */
-#define GUARD_RESULT_OSSL( x , error ) ENSURE((x) == _OSSL_SUCCESS, error)
-
-/**
- * Ensures `x` is not a POSIX error, otherwise return a POSIX error
- */
-#define GUARD_POSIX( x ) __S2N_ENSURE((x) >= S2N_SUCCESS, return S2N_FAILURE)
-
-/**
- * Ensures `x` is strictly not a POSIX error (`-1`), otherwise goto `label`
- */
-#define GUARD_POSIX_STRICT( x ) __S2N_ENSURE((x) == S2N_SUCCESS, return S2N_FAILURE)
-
-/**
- * Ensures `x` is not a POSIX error, otherwise goto `label`
- */
-#define GUARD_POSIX_GOTO( x , label ) __S2N_ENSURE((x) >= S2N_SUCCESS, goto label)
-
-/**
- * Ensures `x` is not a POSIX error, otherwise the function will return `NULL`
- */
-#define GUARD_POSIX_PTR( x ) __S2N_ENSURE((x) >= S2N_SUCCESS, return NULL)
-
-/**
- * Ensures `x` is not `NULL`, otherwise the function will return a POSIX error (`-1`)
- */
-#define GUARD_POSIX_NONNULL( x ) __S2N_ENSURE((x) != NULL, return S2N_FAILURE)
-
-/**
- * Ensures `x` is not a OpenSSL error, otherwise the function will `BAIL` with `error`
- */
-/* TODO: use the OSSL error code in error reporting https://github.com/awslabs/s2n/issues/705 */
-#define GUARD_POSIX_OSSL( x , error ) ENSURE_POSIX((x) == _OSSL_SUCCESS, error)
-
-/**
- * Ensures `x` is not a POSIX error, otherwise the function will return a `S2N_RESULT_ERROR`
- */
-#define GUARD_AS_RESULT( x ) __S2N_ENSURE((x) >= S2N_SUCCESS, return S2N_RESULT_ERROR)
-
-/**
- * Ensures `x` is OK (S2N_RESULT), otherwise the function will return a POSIX error (`-1`)
- */
-#define GUARD_AS_POSIX( x ) __S2N_ENSURE(s2n_result_is_ok(x), return S2N_FAILURE)
-
-/**
- * Performs a safe memcpy
- */
-#define CHECKED_MEMCPY( d , s , n ) __S2N_ENSURE_SAFE_MEMCPY((d), (s), (n), GUARD_RESULT_NONNULL)
-
-/**
- * Performs a safe memset
- */
-#define CHECKED_MEMSET( d , c , n ) __S2N_ENSURE_SAFE_MEMSET((d), (c), (n), ENSURE_REF)
-
-/**
- * Marks a case of a switch statement as able to fall through to the next case
- */
-#if (defined(__clang__) && __clang_major__ >= 10) || (defined(__GNUC__) && __GNUC__ >= 7)
-# define FALL_THROUGH __attribute__((fallthrough))
-#else
-# define FALL_THROUGH ((void)0)
-#endif
-
-/* Returns `true` if s2n is in unit test mode, `false` otherwise */
-bool s2n_in_unit_test();
-
-/* Sets whether s2n is in unit test mode */
-int s2n_in_unit_test_set(bool newval);
-
-#define S2N_IN_INTEG_TEST ( getenv("S2N_INTEG_TEST") != NULL )
-#define S2N_IN_TEST ( s2n_in_unit_test() || S2N_IN_INTEG_TEST )
-
-/**
- * Get the process id
- *
- * Returns:
- * The process ID of the current process
- */
-extern pid_t s2n_actual_getpid();
-
-/* Returns 1 if a and b are equal, in constant time */
-extern bool s2n_constant_time_equals(const uint8_t * a, const uint8_t * b, const uint32_t len);
-
-/* Copy src to dst, or don't copy it, in constant time */
-extern int s2n_constant_time_copy_or_dont(uint8_t * dst, const uint8_t * src, uint32_t len, uint8_t dont);
-
-/* If src contains valid PKCS#1 v1.5 padding of exactly expectlen bytes, decode
- * it into dst, otherwise leave dst alone, in constant time.
- * Always returns zero. */
-extern int s2n_constant_time_pkcs1_unpad_or_dont(uint8_t * dst, const uint8_t * src, uint32_t srclen, uint32_t expectlen);
-
-/**
- * Runs _thecleanup function on _thealloc once _thealloc went out of scope
- */
-#define DEFER_CLEANUP(_thealloc, _thecleanup) \
- __attribute__((cleanup(_thecleanup))) _thealloc
-
-/* Creates cleanup function for pointers from function func which accepts a pointer.
- * This is useful for DEFER_CLEANUP as it passes &_thealloc into _thecleanup function,
- * so if _thealloc is a pointer _thecleanup will receive a pointer to a pointer.*/
-#define DEFINE_POINTER_CLEANUP_FUNC(type, func) \
- static inline void func##_pointer(type *p) { \
- if (p && *p) \
- func(*p); \
- } \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-#define s2n_array_len(array) ((array != NULL) ? (sizeof(array) / sizeof(array[0])) : 0)
-
-extern int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out);
-
-/**
- * Rounds "initial" up to a multiple of "alignment", and stores the result in "out".
- * Raises an error if overflow would occur.
- * NOT CONSTANT TIME.
- */
-extern int s2n_align_to(uint32_t initial, uint32_t alignment, uint32_t* out);
-extern int s2n_add_overflow(uint32_t a, uint32_t b, uint32_t* out);
-extern int s2n_sub_overflow(uint32_t a, uint32_t b, uint32_t* out);
-/* START COMPATIBILITY LAYER */
-
-/**
- * NOTE: This will be removed once everything is using s2n_result
- */
-
-/* `NULL` check a pointer */
-
-/* Note: this macro is replaced by ENSURE_POSIX_REF */
-#define notnull_check(ptr) ENSURE_POSIX_REF(ptr)
-/* Note: this macro is replaced by ENSURE_REF_PTR */
-#define notnull_check_ptr(ptr) ENSURE_REF_PTR(ptr)
-
-/* Range check a number */
-#define gte_check( n , min ) ENSURE_POSIX((n) >= (min), S2N_ERR_SAFETY)
-#define lte_check( n , max ) ENSURE_POSIX((n) <= (max), S2N_ERR_SAFETY)
-#define gt_check( n , min ) ENSURE_POSIX((n) > (min), S2N_ERR_SAFETY)
-#define lt_check( n , max ) ENSURE_POSIX((n) < (max), S2N_ERR_SAFETY)
-#define eq_check( a , b ) ENSURE_POSIX((a) == (b), S2N_ERR_SAFETY)
-#define ne_check( a , b ) ENSURE_POSIX((a) != (b), S2N_ERR_SAFETY)
-#define inclusive_range_check( low, n, high ) \
- do { \
- __typeof( n ) __tmp_n = ( n ); \
- gte_check(__tmp_n, low); \
- lte_check(__tmp_n, high); \
- } while (0)
-#define exclusive_range_check( low, n, high ) \
- do { \
- __typeof( n ) __tmp_n = ( n ); \
- gt_check(__tmp_n, low); \
- lt_check(__tmp_n, high); \
- } while (0)
-
-#define memcpy_check( d , s , n ) __S2N_ENSURE_SAFE_MEMCPY((d), (s), (n), GUARD_POSIX_NONNULL)
-/* This will fail to build if d is an array. Cast the array to a pointer first! */
-#define memset_check( d , c , n ) __S2N_ENSURE_SAFE_MEMSET((d), (c), (n), ENSURE_POSIX_REF)
-
-/* END COMPATIBILITY LAYER */
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "error/s2n_errno.h"
+#include "utils/s2n_ensure.h"
+#include "utils/s2n_result.h"
+
+/* Success signal value for OpenSSL functions */
+#define _OSSL_SUCCESS 1
+
+/**
+ * The goal of s2n_safety is to provide helpers to perform common
+ * checks, which help with code readability.
+ */
+
+/**
+ * Sets the global `errno` and returns with a `S2N_RESULT_ERROR`
+ */
+#define BAIL( x ) do { _S2N_ERROR( ( x ) ); return S2N_RESULT_ERROR; } while (0)
+
+/**
+ * Sets the global `errno` and returns with a POSIX error (`-1`)
+ */
+#define BAIL_POSIX( x ) do { _S2N_ERROR( ( x ) ); return S2N_FAILURE; } while (0)
+
+/**
+ * Sets the global `errno` and returns with a `NULL` pointer value
+ */
+#define BAIL_PTR( x ) do { _S2N_ERROR( ( x ) ); return NULL; } while (0)
+
+/**
+ * Ensures the `condition` is `true`, otherwise the function will `BAIL` with an `error`
+ */
+#define ENSURE( condition , error ) __S2N_ENSURE((condition), BAIL(error))
+
+/**
+ * Ensures the `result` is OK, otherwise the function will `BAIL` with an `error`
+ */
+#define ENSURE_OK( result , error ) __S2N_ENSURE(s2n_result_is_ok(result), BAIL(error))
+
+/**
+ * Ensures `n` is greater than or equal to `min`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
+ */
+#define ENSURE_GTE( n , min ) ENSURE((n) >= (min), S2N_ERR_SAFETY)
+
+/**
+ * Ensures `n` is less than or equal to `max`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
+ */
+#define ENSURE_LTE( n , max ) ENSURE((n) <= (max), S2N_ERR_SAFETY)
+
+/**
+ * Ensures `n` is greater than `min`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
+ */
+#define ENSURE_GT( n , min ) ENSURE((n) > (min), S2N_ERR_SAFETY)
+
+/**
+ * Ensures `n` is less than `min`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
+ */
+#define ENSURE_LT( n , max ) ENSURE((n) < (max), S2N_ERR_SAFETY)
+
+/**
+ * Ensures `a` is equal to `b`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
+ */
+#define ENSURE_EQ( a , b ) ENSURE((a) == (b), S2N_ERR_SAFETY)
+
+/**
+ * Ensures `a` is not equal to `b`, otherwise the function will `BAIL` with a `S2N_ERR_SAFETY` error
+ */
+#define ENSURE_NE( a , b ) ENSURE((a) != (b), S2N_ERR_SAFETY)
+
+/**
+ * Ensures the `condition` is `true`, otherwise the function will `BAIL_POSIX` with an `error`
+ */
+#define ENSURE_POSIX( condition , error ) __S2N_ENSURE((condition), BAIL_POSIX(error))
+
+/**
+ * Ensures the `condition` is `true`, otherwise the function will `BAIL_PTR` with an `error`
+ */
+#define ENSURE_PTR( condition , error ) __S2N_ENSURE((condition), BAIL_PTR(error))
+
+/**
+ * Ensures `x` is not `NULL`, otherwise the function will `BAIL_PTR` with an `error`
+ */
+#define ENSURE_REF_PTR( x ) ENSURE_PTR(S2N_OBJECT_PTR_IS_READABLE(x), S2N_ERR_NULL)
+
+/**
+ * Ensures `x` is a readable reference, otherwise the function will `BAIL` with `S2N_ERR_NULL`
+ */
+#define ENSURE_REF( x ) ENSURE(S2N_OBJECT_PTR_IS_READABLE(x), S2N_ERR_NULL)
+
+/**
+ * Ensures `x` is a readable reference, otherwise the function will `BAIL_POSIX` with `S2N_ERR_NULL`
+ */
+#define ENSURE_POSIX_REF( x ) ENSURE_POSIX(S2N_OBJECT_PTR_IS_READABLE(x), S2N_ERR_NULL)
+
+/**
+ * Ensures `x` is a mutable reference, otherwise the function will `BAIL` with `S2N_ERR_NULL`
+ */
+#define ENSURE_MUT( x ) ENSURE(S2N_OBJECT_PTR_IS_WRITABLE(x), S2N_ERR_NULL)
+
+/**
+ * Ensures `x` is a mutable reference, otherwise the function will `BAIL_POSIX` with `S2N_ERR_NULL`
+ */
+#define ENSURE_POSIX_MUT( x ) ENSURE_POSIX(S2N_OBJECT_PTR_IS_WRITABLE(x), S2N_ERR_NULL)
+
+/**
+ * Ensures `min <= n <= max`
+ */
+#define ENSURE_INCLUSIVE_RANGE( min , n , max ) \
+ do { \
+ __typeof( n ) __tmp_n = ( n ); \
+ ENSURE_GTE(__tmp_n, min); \
+ ENSURE_LTE(__tmp_n, max); \
+ } while(0)
+
+/**
+ * Ensures `min < n < max`
+ */
+#define ENSURE_EXCLUSIVE_RANGE( min , n , max ) \
+ do { \
+ __typeof( n ) __tmp_n = ( n ); \
+ ENSURE_GT(__tmp_n, min); \
+ ENSURE_LT(__tmp_n, max); \
+ } while(0)
+
+/**
+ * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
+ */
+#define PRECONDITION( result ) GUARD_RESULT(__S2N_ENSURE_PRECONDITION(result))
+
+/**
+ * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
+ */
+#define POSTCONDITION( result ) GUARD_RESULT(__S2N_ENSURE_POSTCONDITION(result))
+
+/**
+ * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
+ */
+#define PRECONDITION_POSIX( result ) GUARD_AS_POSIX(__S2N_ENSURE_PRECONDITION(result))
+
+/**
+ * Ensures the `result` is `S2N_RESULT_OK`, otherwise the function will return an error signal
+ */
+#define POSTCONDITION_POSIX( result ) GUARD_AS_POSIX(__S2N_ENSURE_POSTCONDITION(result))
+
+/**
+ * Ensures the `condition` is `true`, otherwise the function will `BAIL` with an `error`.
+ * When the code is built in debug mode, they are checked.
+ * When the code is built in production mode, they are ignored.
+ */
+#define DEBUG_ENSURE( condition, error ) __S2N_ENSURE_DEBUG((condition), BAIL(error))
+
+/**
+ * Ensures the `condition` is `true`, otherwise the function will `BAIL_POSIX` with an `error`.
+ * When the code is built in debug mode, they are checked.
+ * When the code is built in production mode, they are ignored.
+ */
+#define DEBUG_ENSURE_POSIX( condition, error ) __S2N_ENSURE_DEBUG((condition), BAIL_POSIX(error))
+
+/**
+ * Ensures `x` is not an error, otherwise the function will return an error signal
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD( x ) GUARD_POSIX(x)
+
+/**
+ * Ensures `x` is not an error, otherwise goto `label`
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD_GOTO( x , label ) GUARD_POSIX_GOTO((x), (label))
+
+/**
+ * Ensures `x` is not an error, otherwise the function will return `NULL`
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD_PTR( x ) GUARD_POSIX_PTR(x)
+
+/**
+ * Ensures `x` is not `NULL`, otherwise the function will return an error signal
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD_NONNULL( x ) GUARD_POSIX_NONNULL(x)
+
+/**
+ * Ensures `x` is not `NULL`, otherwise goto `label`
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD_NONNULL_GOTO( x , label ) __S2N_ENSURE((x) != NULL, goto label)
+
+/**
+ * Ensures `x` is not `NULL`, otherwise the function will return `NULL`
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD_NONNULL_PTR( x ) __S2N_ENSURE((x) != NULL, return NULL)
+
+/**
+ * Ensures `x` is not a OpenSSL error, otherwise the function will return an error signal
+ *
+ * Note: this currently accepts POSIX error signals but will transition to accept s2n_result
+ */
+#define GUARD_OSSL( x, error ) GUARD_POSIX_OSSL((x), (error))
+
+/**
+ * Ensures `x` is ok, otherwise the function will return an `S2N_RESULT_ERROR`
+ */
+#define GUARD_RESULT( x ) __S2N_ENSURE(s2n_result_is_ok(x), return S2N_RESULT_ERROR)
+
+/**
+ * Ensures `x` is ok, otherwise goto `label`
+ */
+#define GUARD_RESULT_GOTO( x, label ) __S2N_ENSURE(s2n_result_is_ok(x), goto label)
+
+/**
+ * Ensures `x` is ok, otherwise the function will return `NULL`
+ */
+#define GUARD_RESULT_PTR( x ) __S2N_ENSURE(s2n_result_is_ok(x), return NULL)
+
+/**
+ * Ensures `x` is not `NULL`, otherwise the function will return an `S2N_RESULT_ERROR`
+ */
+#define GUARD_RESULT_NONNULL( x ) __S2N_ENSURE((x) != NULL, return S2N_RESULT_ERROR)
+
+/**
+ * Ensures `x` is not a OpenSSL error, otherwise the function will `BAIL` with `error`
+ */
+/* TODO: use the OSSL error code in error reporting https://github.com/awslabs/s2n/issues/705 */
+#define GUARD_RESULT_OSSL( x , error ) ENSURE((x) == _OSSL_SUCCESS, error)
+
+/**
+ * Ensures `x` is not a POSIX error, otherwise return a POSIX error
+ */
+#define GUARD_POSIX( x ) __S2N_ENSURE((x) >= S2N_SUCCESS, return S2N_FAILURE)
+
+/**
+ * Ensures `x` is strictly not a POSIX error (`-1`), otherwise goto `label`
+ */
+#define GUARD_POSIX_STRICT( x ) __S2N_ENSURE((x) == S2N_SUCCESS, return S2N_FAILURE)
+
+/**
+ * Ensures `x` is not a POSIX error, otherwise goto `label`
+ */
+#define GUARD_POSIX_GOTO( x , label ) __S2N_ENSURE((x) >= S2N_SUCCESS, goto label)
+
+/**
+ * Ensures `x` is not a POSIX error, otherwise the function will return `NULL`
+ */
+#define GUARD_POSIX_PTR( x ) __S2N_ENSURE((x) >= S2N_SUCCESS, return NULL)
+
+/**
+ * Ensures `x` is not `NULL`, otherwise the function will return a POSIX error (`-1`)
+ */
+#define GUARD_POSIX_NONNULL( x ) __S2N_ENSURE((x) != NULL, return S2N_FAILURE)
+
+/**
+ * Ensures `x` is not a OpenSSL error, otherwise the function will `BAIL` with `error`
+ */
+/* TODO: use the OSSL error code in error reporting https://github.com/awslabs/s2n/issues/705 */
+#define GUARD_POSIX_OSSL( x , error ) ENSURE_POSIX((x) == _OSSL_SUCCESS, error)
+
+/**
+ * Ensures `x` is not a POSIX error, otherwise the function will return a `S2N_RESULT_ERROR`
+ */
+#define GUARD_AS_RESULT( x ) __S2N_ENSURE((x) >= S2N_SUCCESS, return S2N_RESULT_ERROR)
+
+/**
+ * Ensures `x` is OK (S2N_RESULT), otherwise the function will return a POSIX error (`-1`)
+ */
+#define GUARD_AS_POSIX( x ) __S2N_ENSURE(s2n_result_is_ok(x), return S2N_FAILURE)
+
+/**
+ * Performs a safe memcpy
+ */
+#define CHECKED_MEMCPY( d , s , n ) __S2N_ENSURE_SAFE_MEMCPY((d), (s), (n), GUARD_RESULT_NONNULL)
+
+/**
+ * Performs a safe memset
+ */
+#define CHECKED_MEMSET( d , c , n ) __S2N_ENSURE_SAFE_MEMSET((d), (c), (n), ENSURE_REF)
+
+/**
+ * Marks a case of a switch statement as able to fall through to the next case
+ */
+#if (defined(__clang__) && __clang_major__ >= 10) || (defined(__GNUC__) && __GNUC__ >= 7)
+# define FALL_THROUGH __attribute__((fallthrough))
+#else
+# define FALL_THROUGH ((void)0)
+#endif
+
+/* Returns `true` if s2n is in unit test mode, `false` otherwise */
+bool s2n_in_unit_test();
+
+/* Sets whether s2n is in unit test mode */
+int s2n_in_unit_test_set(bool newval);
+
+#define S2N_IN_INTEG_TEST ( getenv("S2N_INTEG_TEST") != NULL )
+#define S2N_IN_TEST ( s2n_in_unit_test() || S2N_IN_INTEG_TEST )
+
+/**
+ * Get the process id
+ *
+ * Returns:
+ * The process ID of the current process
+ */
+extern pid_t s2n_actual_getpid();
+
+/* Returns 1 if a and b are equal, in constant time */
+extern bool s2n_constant_time_equals(const uint8_t * a, const uint8_t * b, const uint32_t len);
+
+/* Copy src to dst, or don't copy it, in constant time */
+extern int s2n_constant_time_copy_or_dont(uint8_t * dst, const uint8_t * src, uint32_t len, uint8_t dont);
+
+/* If src contains valid PKCS#1 v1.5 padding of exactly expectlen bytes, decode
+ * it into dst, otherwise leave dst alone, in constant time.
+ * Always returns zero. */
+extern int s2n_constant_time_pkcs1_unpad_or_dont(uint8_t * dst, const uint8_t * src, uint32_t srclen, uint32_t expectlen);
+
+/**
+ * Runs _thecleanup function on _thealloc once _thealloc went out of scope
+ */
+#define DEFER_CLEANUP(_thealloc, _thecleanup) \
+ __attribute__((cleanup(_thecleanup))) _thealloc
+
+/* Creates cleanup function for pointers from function func which accepts a pointer.
+ * This is useful for DEFER_CLEANUP as it passes &_thealloc into _thecleanup function,
+ * so if _thealloc is a pointer _thecleanup will receive a pointer to a pointer.*/
+#define DEFINE_POINTER_CLEANUP_FUNC(type, func) \
+ static inline void func##_pointer(type *p) { \
+ if (p && *p) \
+ func(*p); \
+ } \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
+#define s2n_array_len(array) ((array != NULL) ? (sizeof(array) / sizeof(array[0])) : 0)
+
+extern int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out);
+
+/**
+ * Rounds "initial" up to a multiple of "alignment", and stores the result in "out".
+ * Raises an error if overflow would occur.
+ * NOT CONSTANT TIME.
+ */
+extern int s2n_align_to(uint32_t initial, uint32_t alignment, uint32_t* out);
+extern int s2n_add_overflow(uint32_t a, uint32_t b, uint32_t* out);
+extern int s2n_sub_overflow(uint32_t a, uint32_t b, uint32_t* out);
+/* START COMPATIBILITY LAYER */
+
+/**
+ * NOTE: This will be removed once everything is using s2n_result
+ */
+
+/* `NULL` check a pointer */
+
+/* Note: this macro is replaced by ENSURE_POSIX_REF */
+#define notnull_check(ptr) ENSURE_POSIX_REF(ptr)
+/* Note: this macro is replaced by ENSURE_REF_PTR */
+#define notnull_check_ptr(ptr) ENSURE_REF_PTR(ptr)
+
+/* Range check a number */
+#define gte_check( n , min ) ENSURE_POSIX((n) >= (min), S2N_ERR_SAFETY)
+#define lte_check( n , max ) ENSURE_POSIX((n) <= (max), S2N_ERR_SAFETY)
+#define gt_check( n , min ) ENSURE_POSIX((n) > (min), S2N_ERR_SAFETY)
+#define lt_check( n , max ) ENSURE_POSIX((n) < (max), S2N_ERR_SAFETY)
+#define eq_check( a , b ) ENSURE_POSIX((a) == (b), S2N_ERR_SAFETY)
+#define ne_check( a , b ) ENSURE_POSIX((a) != (b), S2N_ERR_SAFETY)
+#define inclusive_range_check( low, n, high ) \
+ do { \
+ __typeof( n ) __tmp_n = ( n ); \
+ gte_check(__tmp_n, low); \
+ lte_check(__tmp_n, high); \
+ } while (0)
+#define exclusive_range_check( low, n, high ) \
+ do { \
+ __typeof( n ) __tmp_n = ( n ); \
+ gt_check(__tmp_n, low); \
+ lt_check(__tmp_n, high); \
+ } while (0)
+
+#define memcpy_check( d , s , n ) __S2N_ENSURE_SAFE_MEMCPY((d), (s), (n), GUARD_POSIX_NONNULL)
+/* This will fail to build if d is an array. Cast the array to a pointer first! */
+#define memset_check( d , c , n ) __S2N_ENSURE_SAFE_MEMSET((d), (c), (n), ENSURE_POSIX_REF)
+
+/* END COMPATIBILITY LAYER */
diff --git a/contrib/restricted/aws/s2n/utils/s2n_set.c b/contrib/restricted/aws/s2n/utils/s2n_set.c
index 4073a4cc5d..9c5d5769fa 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_set.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_set.c
@@ -1,147 +1,147 @@
-/*
- * 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 "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_result.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_set.h"
-#include "utils/s2n_array.h"
-
-#define S2N_INITIAL_SET_SIZE 16
-
-S2N_RESULT s2n_set_validate(const struct s2n_set *set)
-{
- ENSURE_REF(set);
- GUARD_RESULT(s2n_array_validate(set->data));
- return S2N_RESULT_OK;
-}
-
-/* Sets "out" to the index at which the element should be inserted.
- * Returns an error if the element already exists */
-static S2N_RESULT s2n_set_binary_search(struct s2n_set *set, void *element, uint32_t* out)
-{
- GUARD_RESULT(s2n_set_validate(set));
- ENSURE(S2N_MEM_IS_READABLE(element, set->data->element_size), S2N_ERR_NULL);
- ENSURE_REF(out);
- struct s2n_array *array = set->data;
- int (*comparator)(const void*, const void*) = set->comparator;
-
- uint32_t len = 0;
- GUARD_RESULT(s2n_array_num_elements(array, &len));
-
- if (len == 0) {
- *out = 0;
- return S2N_RESULT_OK;
- }
-
- /* Use 64 bit ints to avoid possibility of overflow */
- int64_t low = 0;
- int64_t top = len - 1;
-
- while (low <= top) {
- int64_t mid = low + ((top - low) / 2);
- void* array_element = NULL;
- GUARD_RESULT(s2n_array_get(array, mid, &array_element));
- int m = comparator(array_element, element);
-
- /* the element is already in the set */
- if (m == 0) {
- BAIL(S2N_ERR_SET_DUPLICATE_VALUE);
- }
-
- if (m > 0) {
- top = mid - 1;
- } else {
- low = mid + 1;
- }
- }
-
- *out = low;
- return S2N_RESULT_OK;
-}
-
-struct s2n_set *s2n_set_new(uint32_t element_size, int (*comparator)(const void*, const void*))
-{
- notnull_check_ptr(comparator);
- struct s2n_blob mem = {0};
- GUARD_POSIX_PTR(s2n_alloc(&mem, sizeof(struct s2n_set)));
- struct s2n_set *set = (void *) mem.data;
- *set = (struct s2n_set) {.data = s2n_array_new(element_size), .comparator = comparator};
- if(set->data == NULL) {
- GUARD_POSIX_PTR(s2n_free(&mem));
- return NULL;
- }
- return set;
-}
-
-S2N_RESULT s2n_set_add(struct s2n_set *set, void *element)
-{
- GUARD_RESULT(s2n_set_validate(set));
-
- uint32_t index = 0;
- GUARD_RESULT(s2n_set_binary_search(set, element, &index));
- GUARD_RESULT(s2n_array_insert_and_copy(set->data, index, element));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_set_get(struct s2n_set *set, uint32_t index, void **element)
-{
- GUARD_RESULT(s2n_set_validate(set));
- ENSURE_REF(element);
-
- GUARD_RESULT(s2n_array_get(set->data, index, element));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_set_remove(struct s2n_set *set, uint32_t index)
-{
- GUARD_RESULT(s2n_set_validate(set));
- GUARD_RESULT(s2n_array_remove(set->data, index));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_set_free_p(struct s2n_set **pset)
-{
- ENSURE_REF(pset);
- struct s2n_set *set = *pset;
-
- ENSURE_REF(set);
- GUARD_RESULT(s2n_array_free(set->data));
-
- /* And finally the set object. */
- GUARD_AS_RESULT(s2n_free_object((uint8_t **)pset, sizeof(struct s2n_set)));
-
- return S2N_RESULT_OK;
-
-}
-
-S2N_RESULT s2n_set_free(struct s2n_set *set)
-{
- ENSURE_REF(set);
- return s2n_set_free_p(&set);
-}
-
-
-S2N_RESULT s2n_set_len(struct s2n_set *set, uint32_t *len)
-{
- GUARD_RESULT(s2n_set_validate(set));
-
- GUARD_RESULT(s2n_array_num_elements(set->data, len));
-
- return S2N_RESULT_OK;
-}
+/*
+ * 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 "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_set.h"
+#include "utils/s2n_array.h"
+
+#define S2N_INITIAL_SET_SIZE 16
+
+S2N_RESULT s2n_set_validate(const struct s2n_set *set)
+{
+ ENSURE_REF(set);
+ GUARD_RESULT(s2n_array_validate(set->data));
+ return S2N_RESULT_OK;
+}
+
+/* Sets "out" to the index at which the element should be inserted.
+ * Returns an error if the element already exists */
+static S2N_RESULT s2n_set_binary_search(struct s2n_set *set, void *element, uint32_t* out)
+{
+ GUARD_RESULT(s2n_set_validate(set));
+ ENSURE(S2N_MEM_IS_READABLE(element, set->data->element_size), S2N_ERR_NULL);
+ ENSURE_REF(out);
+ struct s2n_array *array = set->data;
+ int (*comparator)(const void*, const void*) = set->comparator;
+
+ uint32_t len = 0;
+ GUARD_RESULT(s2n_array_num_elements(array, &len));
+
+ if (len == 0) {
+ *out = 0;
+ return S2N_RESULT_OK;
+ }
+
+ /* Use 64 bit ints to avoid possibility of overflow */
+ int64_t low = 0;
+ int64_t top = len - 1;
+
+ while (low <= top) {
+ int64_t mid = low + ((top - low) / 2);
+ void* array_element = NULL;
+ GUARD_RESULT(s2n_array_get(array, mid, &array_element));
+ int m = comparator(array_element, element);
+
+ /* the element is already in the set */
+ if (m == 0) {
+ BAIL(S2N_ERR_SET_DUPLICATE_VALUE);
+ }
+
+ if (m > 0) {
+ top = mid - 1;
+ } else {
+ low = mid + 1;
+ }
+ }
+
+ *out = low;
+ return S2N_RESULT_OK;
+}
+
+struct s2n_set *s2n_set_new(uint32_t element_size, int (*comparator)(const void*, const void*))
+{
+ notnull_check_ptr(comparator);
+ struct s2n_blob mem = {0};
+ GUARD_POSIX_PTR(s2n_alloc(&mem, sizeof(struct s2n_set)));
+ struct s2n_set *set = (void *) mem.data;
+ *set = (struct s2n_set) {.data = s2n_array_new(element_size), .comparator = comparator};
+ if(set->data == NULL) {
+ GUARD_POSIX_PTR(s2n_free(&mem));
+ return NULL;
+ }
+ return set;
+}
+
+S2N_RESULT s2n_set_add(struct s2n_set *set, void *element)
+{
+ GUARD_RESULT(s2n_set_validate(set));
+
+ uint32_t index = 0;
+ GUARD_RESULT(s2n_set_binary_search(set, element, &index));
+ GUARD_RESULT(s2n_array_insert_and_copy(set->data, index, element));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_set_get(struct s2n_set *set, uint32_t index, void **element)
+{
+ GUARD_RESULT(s2n_set_validate(set));
+ ENSURE_REF(element);
+
+ GUARD_RESULT(s2n_array_get(set->data, index, element));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_set_remove(struct s2n_set *set, uint32_t index)
+{
+ GUARD_RESULT(s2n_set_validate(set));
+ GUARD_RESULT(s2n_array_remove(set->data, index));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_set_free_p(struct s2n_set **pset)
+{
+ ENSURE_REF(pset);
+ struct s2n_set *set = *pset;
+
+ ENSURE_REF(set);
+ GUARD_RESULT(s2n_array_free(set->data));
+
+ /* And finally the set object. */
+ GUARD_AS_RESULT(s2n_free_object((uint8_t **)pset, sizeof(struct s2n_set)));
+
+ return S2N_RESULT_OK;
+
+}
+
+S2N_RESULT s2n_set_free(struct s2n_set *set)
+{
+ ENSURE_REF(set);
+ return s2n_set_free_p(&set);
+}
+
+
+S2N_RESULT s2n_set_len(struct s2n_set *set, uint32_t *len)
+{
+ GUARD_RESULT(s2n_set_validate(set));
+
+ GUARD_RESULT(s2n_array_num_elements(set->data, len));
+
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_set.h b/contrib/restricted/aws/s2n/utils/s2n_set.h
index b3dba15453..508663a19d 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_set.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_set.h
@@ -1,33 +1,33 @@
-/*
- * 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.
- */
-#pragma once
-
-#include <s2n.h>
-#include "utils/s2n_result.h"
-#include "utils/s2n_array.h"
-
-struct s2n_set {
- struct s2n_array *data;
- int (*comparator)(const void*, const void*);
-};
-
-extern S2N_RESULT s2n_set_validate(const struct s2n_set *set);
-extern struct s2n_set *s2n_set_new(uint32_t element_size, int (*comparator)(const void*, const void*));
-extern S2N_RESULT s2n_set_add(struct s2n_set *set, void *element);
-extern S2N_RESULT s2n_set_get(struct s2n_set *set, uint32_t index, void **element);
-extern S2N_RESULT s2n_set_remove(struct s2n_set *set, uint32_t index);
-extern S2N_RESULT s2n_set_free_p(struct s2n_set **pset);
-extern S2N_RESULT s2n_set_free(struct s2n_set *set);
-extern S2N_RESULT s2n_set_len(struct s2n_set *set, uint32_t *len);
+/*
+ * 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.
+ */
+#pragma once
+
+#include <s2n.h>
+#include "utils/s2n_result.h"
+#include "utils/s2n_array.h"
+
+struct s2n_set {
+ struct s2n_array *data;
+ int (*comparator)(const void*, const void*);
+};
+
+extern S2N_RESULT s2n_set_validate(const struct s2n_set *set);
+extern struct s2n_set *s2n_set_new(uint32_t element_size, int (*comparator)(const void*, const void*));
+extern S2N_RESULT s2n_set_add(struct s2n_set *set, void *element);
+extern S2N_RESULT s2n_set_get(struct s2n_set *set, uint32_t index, void **element);
+extern S2N_RESULT s2n_set_remove(struct s2n_set *set, uint32_t index);
+extern S2N_RESULT s2n_set_free_p(struct s2n_set **pset);
+extern S2N_RESULT s2n_set_free(struct s2n_set *set);
+extern S2N_RESULT s2n_set_len(struct s2n_set *set, uint32_t *len);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_socket.c b/contrib/restricted/aws/s2n/utils/s2n_socket.c
index daefd1168a..faef725624 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_socket.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_socket.c
@@ -1,226 +1,226 @@
-/*
- * 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 <tls/s2n_connection.h>
-
-#include <utils/s2n_socket.h>
-#include <utils/s2n_safety.h>
-
-#include <netinet/tcp.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#if TCP_CORK
- #define S2N_CORK TCP_CORK
- #define S2N_CORK_ON 1
- #define S2N_CORK_OFF 0
-#elif TCP_NOPUSH
- #define S2N_CORK TCP_NOPUSH
- #define S2N_CORK_ON 1
- #define S2N_CORK_OFF 0
-#elif TCP_NODELAY
- #define S2N_CORK TCP_NODELAY
- #define S2N_CORK_ON 0
- #define S2N_CORK_OFF 1
-#endif
-
-int s2n_socket_quickack(struct s2n_connection *conn)
-{
-#ifdef TCP_QUICKACK
- if (!conn->managed_io) {
- return 0;
- }
-
- struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
- if (r_io_ctx->tcp_quickack_set) {
- return 0;
- }
-
- /* Ignore the return value, if it fails it fails */
- int optval = 1;
- if (setsockopt(r_io_ctx->fd, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval)) == 0) {
- r_io_ctx->tcp_quickack_set = 1;
- }
-#endif
-
- return 0;
-}
-
-int s2n_socket_write_snapshot(struct s2n_connection *conn)
-{
-#ifdef S2N_CORK
- socklen_t corklen = sizeof(int);
-
- struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
- notnull_check(w_io_ctx);
-
- getsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &w_io_ctx->original_cork_val, &corklen);
- eq_check(corklen, sizeof(int));
- w_io_ctx->original_cork_is_set = 1;
-#endif
-
- return 0;
-}
-
-
-int s2n_socket_read_snapshot(struct s2n_connection *conn)
-{
-#ifdef SO_RCVLOWAT
- socklen_t watlen = sizeof(int);
-
- struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
- notnull_check(r_io_ctx);
-
- getsockopt(r_io_ctx->fd, SOL_SOCKET, SO_RCVLOWAT, &r_io_ctx->original_rcvlowat_val, &watlen);
- eq_check(watlen, sizeof(int));
- r_io_ctx->original_rcvlowat_is_set = 1;
-#endif
-
- return 0;
-}
-
-int s2n_socket_write_restore(struct s2n_connection *conn)
-{
-#ifdef S2N_CORK
- struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
- notnull_check(w_io_ctx);
-
- if (!w_io_ctx->original_cork_is_set) {
- return 0;
- }
- setsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &w_io_ctx->original_cork_val, sizeof(w_io_ctx->original_cork_val));
- w_io_ctx->original_cork_is_set = 0;
-#endif
-
- return 0;
-}
-
-int s2n_socket_read_restore(struct s2n_connection *conn)
-{
-#ifdef SO_RCVLOWAT
- struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
- notnull_check(r_io_ctx);
-
- if (!r_io_ctx->original_rcvlowat_is_set) {
- return 0;
- }
- setsockopt(r_io_ctx->fd, SOL_SOCKET, SO_RCVLOWAT, &r_io_ctx->original_rcvlowat_val, sizeof(r_io_ctx->original_rcvlowat_val));
- r_io_ctx->original_rcvlowat_is_set = 0;
-#endif
-
- return 0;
-}
-
-int s2n_socket_was_corked(struct s2n_connection *conn)
-{
- /* If we're not using custom I/O and a send fd has not been set yet, return false*/
- if (!conn->managed_io || !conn->send) {
- return 0;
- }
-
- struct s2n_socket_write_io_context *io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
- notnull_check(io_ctx);
-
- return io_ctx->original_cork_val;
-}
-
-int s2n_socket_write_cork(struct s2n_connection *conn)
-{
-#ifdef S2N_CORK
- int optval = S2N_CORK_ON;
-
- struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
- notnull_check(w_io_ctx);
-
- /* Ignore the return value, if it fails it fails */
- setsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &optval, sizeof(optval));
-#endif
-
- return 0;
-}
-
-int s2n_socket_write_uncork(struct s2n_connection *conn)
-{
-#ifdef S2N_CORK
- int optval = S2N_CORK_OFF;
-
- struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
- notnull_check(w_io_ctx);
-
- /* Ignore the return value, if it fails it fails */
- setsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &optval, sizeof(optval));
-#endif
-
- return 0;
-}
-
-int s2n_socket_set_read_size(struct s2n_connection *conn, int size)
-{
-#ifdef SO_RCVLOWAT
- struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
- notnull_check(r_io_ctx);
-
- setsockopt(r_io_ctx->fd, SOL_SOCKET, SO_RCVLOWAT, &size, sizeof(size));
-#endif
-
- return 0;
-}
-
-int s2n_socket_read(void *io_context, uint8_t *buf, uint32_t len)
-{
- int rfd = ((struct s2n_socket_read_io_context*) io_context)->fd;
- if (rfd < 0) {
- errno = EBADF;
- S2N_ERROR(S2N_ERR_BAD_FD);
- }
-
- /* Clear the quickack flag so we know to reset it */
- ((struct s2n_socket_read_io_context*) io_context)->tcp_quickack_set = 0;
-
- /* On success, the number of bytes read is returned. On failure, -1 is
- * returned and errno is set appropriately. */
- return read(rfd, buf, len);
-}
-
-int s2n_socket_write(void *io_context, const uint8_t *buf, uint32_t len)
-{
- int wfd = ((struct s2n_socket_write_io_context*) io_context)->fd;
- if (wfd < 0) {
- errno = EBADF;
- S2N_ERROR(S2N_ERR_BAD_FD);
- }
-
- /* On success, the number of bytes written is returned. On failure, -1 is
- * returned and errno is set appropriately. */
- return write(wfd, buf, len);
-}
-
-int s2n_socket_is_ipv6(int fd, uint8_t *ipv6)
-{
- notnull_check(ipv6);
-
- socklen_t len;
- struct sockaddr_storage addr;
- len = sizeof (addr);
- GUARD(getpeername(fd, (struct sockaddr*)&addr, &len));
-
- *ipv6 = 0;
- if (AF_INET6 == addr.ss_family) {
- *ipv6 = 1;
- }
-
- 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 <tls/s2n_connection.h>
+
+#include <utils/s2n_socket.h>
+#include <utils/s2n_safety.h>
+
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#if TCP_CORK
+ #define S2N_CORK TCP_CORK
+ #define S2N_CORK_ON 1
+ #define S2N_CORK_OFF 0
+#elif TCP_NOPUSH
+ #define S2N_CORK TCP_NOPUSH
+ #define S2N_CORK_ON 1
+ #define S2N_CORK_OFF 0
+#elif TCP_NODELAY
+ #define S2N_CORK TCP_NODELAY
+ #define S2N_CORK_ON 0
+ #define S2N_CORK_OFF 1
+#endif
+
+int s2n_socket_quickack(struct s2n_connection *conn)
+{
+#ifdef TCP_QUICKACK
+ if (!conn->managed_io) {
+ return 0;
+ }
+
+ struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
+ if (r_io_ctx->tcp_quickack_set) {
+ return 0;
+ }
+
+ /* Ignore the return value, if it fails it fails */
+ int optval = 1;
+ if (setsockopt(r_io_ctx->fd, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval)) == 0) {
+ r_io_ctx->tcp_quickack_set = 1;
+ }
+#endif
+
+ return 0;
+}
+
+int s2n_socket_write_snapshot(struct s2n_connection *conn)
+{
+#ifdef S2N_CORK
+ socklen_t corklen = sizeof(int);
+
+ struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
+ notnull_check(w_io_ctx);
+
+ getsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &w_io_ctx->original_cork_val, &corklen);
+ eq_check(corklen, sizeof(int));
+ w_io_ctx->original_cork_is_set = 1;
+#endif
+
+ return 0;
+}
+
+
+int s2n_socket_read_snapshot(struct s2n_connection *conn)
+{
+#ifdef SO_RCVLOWAT
+ socklen_t watlen = sizeof(int);
+
+ struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
+ notnull_check(r_io_ctx);
+
+ getsockopt(r_io_ctx->fd, SOL_SOCKET, SO_RCVLOWAT, &r_io_ctx->original_rcvlowat_val, &watlen);
+ eq_check(watlen, sizeof(int));
+ r_io_ctx->original_rcvlowat_is_set = 1;
+#endif
+
+ return 0;
+}
+
+int s2n_socket_write_restore(struct s2n_connection *conn)
+{
+#ifdef S2N_CORK
+ struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
+ notnull_check(w_io_ctx);
+
+ if (!w_io_ctx->original_cork_is_set) {
+ return 0;
+ }
+ setsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &w_io_ctx->original_cork_val, sizeof(w_io_ctx->original_cork_val));
+ w_io_ctx->original_cork_is_set = 0;
+#endif
+
+ return 0;
+}
+
+int s2n_socket_read_restore(struct s2n_connection *conn)
+{
+#ifdef SO_RCVLOWAT
+ struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
+ notnull_check(r_io_ctx);
+
+ if (!r_io_ctx->original_rcvlowat_is_set) {
+ return 0;
+ }
+ setsockopt(r_io_ctx->fd, SOL_SOCKET, SO_RCVLOWAT, &r_io_ctx->original_rcvlowat_val, sizeof(r_io_ctx->original_rcvlowat_val));
+ r_io_ctx->original_rcvlowat_is_set = 0;
+#endif
+
+ return 0;
+}
+
+int s2n_socket_was_corked(struct s2n_connection *conn)
+{
+ /* If we're not using custom I/O and a send fd has not been set yet, return false*/
+ if (!conn->managed_io || !conn->send) {
+ return 0;
+ }
+
+ struct s2n_socket_write_io_context *io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
+ notnull_check(io_ctx);
+
+ return io_ctx->original_cork_val;
+}
+
+int s2n_socket_write_cork(struct s2n_connection *conn)
+{
+#ifdef S2N_CORK
+ int optval = S2N_CORK_ON;
+
+ struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
+ notnull_check(w_io_ctx);
+
+ /* Ignore the return value, if it fails it fails */
+ setsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &optval, sizeof(optval));
+#endif
+
+ return 0;
+}
+
+int s2n_socket_write_uncork(struct s2n_connection *conn)
+{
+#ifdef S2N_CORK
+ int optval = S2N_CORK_OFF;
+
+ struct s2n_socket_write_io_context *w_io_ctx = (struct s2n_socket_write_io_context *) conn->send_io_context;
+ notnull_check(w_io_ctx);
+
+ /* Ignore the return value, if it fails it fails */
+ setsockopt(w_io_ctx->fd, IPPROTO_TCP, S2N_CORK, &optval, sizeof(optval));
+#endif
+
+ return 0;
+}
+
+int s2n_socket_set_read_size(struct s2n_connection *conn, int size)
+{
+#ifdef SO_RCVLOWAT
+ struct s2n_socket_read_io_context *r_io_ctx = (struct s2n_socket_read_io_context *) conn->recv_io_context;
+ notnull_check(r_io_ctx);
+
+ setsockopt(r_io_ctx->fd, SOL_SOCKET, SO_RCVLOWAT, &size, sizeof(size));
+#endif
+
+ return 0;
+}
+
+int s2n_socket_read(void *io_context, uint8_t *buf, uint32_t len)
+{
+ int rfd = ((struct s2n_socket_read_io_context*) io_context)->fd;
+ if (rfd < 0) {
+ errno = EBADF;
+ S2N_ERROR(S2N_ERR_BAD_FD);
+ }
+
+ /* Clear the quickack flag so we know to reset it */
+ ((struct s2n_socket_read_io_context*) io_context)->tcp_quickack_set = 0;
+
+ /* On success, the number of bytes read is returned. On failure, -1 is
+ * returned and errno is set appropriately. */
+ return read(rfd, buf, len);
+}
+
+int s2n_socket_write(void *io_context, const uint8_t *buf, uint32_t len)
+{
+ int wfd = ((struct s2n_socket_write_io_context*) io_context)->fd;
+ if (wfd < 0) {
+ errno = EBADF;
+ S2N_ERROR(S2N_ERR_BAD_FD);
+ }
+
+ /* On success, the number of bytes written is returned. On failure, -1 is
+ * returned and errno is set appropriately. */
+ return write(wfd, buf, len);
+}
+
+int s2n_socket_is_ipv6(int fd, uint8_t *ipv6)
+{
+ notnull_check(ipv6);
+
+ socklen_t len;
+ struct sockaddr_storage addr;
+ len = sizeof (addr);
+ GUARD(getpeername(fd, (struct sockaddr*)&addr, &len));
+
+ *ipv6 = 0;
+ if (AF_INET6 == addr.ss_family) {
+ *ipv6 = 1;
+ }
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_socket.h b/contrib/restricted/aws/s2n/utils/s2n_socket.h
index 693ac758a3..12cd05c7b8 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_socket.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_socket.h
@@ -1,53 +1,53 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "tls/s2n_connection.h"
-
-/* The default read I/O context for communication over a socket */
-struct s2n_socket_read_io_context {
- /* The peer's fd */
- int fd;
-
- /* Has TCP_QUICKACK been set since the last read */
- unsigned int tcp_quickack_set:1;
- /* Original SO_RCVLOWAT socket option settings before s2n takes over the fd */
- unsigned int original_rcvlowat_is_set:1;
- int original_rcvlowat_val;
-};
-
-/* The default write I/O context for communication over a socket */
-struct s2n_socket_write_io_context {
- /* The peer's fd */
- int fd;
-
- /* Original TCP_CORK socket option settings before s2n takes over the fd */
- unsigned int original_cork_is_set:1;
- int original_cork_val;
-};
-
-extern int s2n_socket_quickack(struct s2n_connection *conn);
-extern int s2n_socket_read_snapshot(struct s2n_connection *conn);
-extern int s2n_socket_write_snapshot(struct s2n_connection *conn);
-extern int s2n_socket_read_restore(struct s2n_connection *conn);
-extern int s2n_socket_write_restore(struct s2n_connection *conn);
-extern int s2n_socket_was_corked(struct s2n_connection *conn);
-extern int s2n_socket_write_cork(struct s2n_connection *conn);
-extern int s2n_socket_write_uncork(struct s2n_connection *conn);
-extern int s2n_socket_set_read_size(struct s2n_connection *conn, int size);
-extern int s2n_socket_read(void *io_context, uint8_t *buf, uint32_t len);
-extern int s2n_socket_write(void *io_context, const uint8_t *buf, uint32_t len);
-extern int s2n_socket_is_ipv6(int fd, uint8_t *ipv6);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "tls/s2n_connection.h"
+
+/* The default read I/O context for communication over a socket */
+struct s2n_socket_read_io_context {
+ /* The peer's fd */
+ int fd;
+
+ /* Has TCP_QUICKACK been set since the last read */
+ unsigned int tcp_quickack_set:1;
+ /* Original SO_RCVLOWAT socket option settings before s2n takes over the fd */
+ unsigned int original_rcvlowat_is_set:1;
+ int original_rcvlowat_val;
+};
+
+/* The default write I/O context for communication over a socket */
+struct s2n_socket_write_io_context {
+ /* The peer's fd */
+ int fd;
+
+ /* Original TCP_CORK socket option settings before s2n takes over the fd */
+ unsigned int original_cork_is_set:1;
+ int original_cork_val;
+};
+
+extern int s2n_socket_quickack(struct s2n_connection *conn);
+extern int s2n_socket_read_snapshot(struct s2n_connection *conn);
+extern int s2n_socket_write_snapshot(struct s2n_connection *conn);
+extern int s2n_socket_read_restore(struct s2n_connection *conn);
+extern int s2n_socket_write_restore(struct s2n_connection *conn);
+extern int s2n_socket_was_corked(struct s2n_connection *conn);
+extern int s2n_socket_write_cork(struct s2n_connection *conn);
+extern int s2n_socket_write_uncork(struct s2n_connection *conn);
+extern int s2n_socket_set_read_size(struct s2n_connection *conn, int size);
+extern int s2n_socket_read(void *io_context, uint8_t *buf, uint32_t len);
+extern int s2n_socket_write(void *io_context, const uint8_t *buf, uint32_t len);
+extern int s2n_socket_is_ipv6(int fd, uint8_t *ipv6);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_str.c b/contrib/restricted/aws/s2n/utils/s2n_str.c
index a1be56b427..a80e7a2ed8 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_str.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_str.c
@@ -1,49 +1,49 @@
-/*
- * 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 <string.h>
-#include <sys/param.h>
-#include "utils/s2n_str.h"
-
-char *s2n_strcpy(char *buf, char *last, const char *str) {
-
-/* CBMC pointer checks need to be disabled to compare buf and last for
- * the case where they are the same. */
-#pragma CPROVER check push
-#pragma CPROVER check disable "pointer"
-
- if (buf >= last) {
- return buf;
- }
-
-#pragma CPROVER check pop
-
- if (NULL == str) {
- *buf = '\0';
- return buf;
- }
-
- /* Free bytes needs to be one byte smaller than size of a storage,
- * as strncpy always writes '\0', but doesn't include it in n
- */
- size_t bytes_to_copy = MIN(last - buf - 1, strlen(str));
-
- char *p = buf;
- if (bytes_to_copy > 0) {
- p = (char *)memcpy(buf, str, bytes_to_copy) + bytes_to_copy;
- }
- *p = '\0';
-
- return p;
-}
+/*
+ * 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 <string.h>
+#include <sys/param.h>
+#include "utils/s2n_str.h"
+
+char *s2n_strcpy(char *buf, char *last, const char *str) {
+
+/* CBMC pointer checks need to be disabled to compare buf and last for
+ * the case where they are the same. */
+#pragma CPROVER check push
+#pragma CPROVER check disable "pointer"
+
+ if (buf >= last) {
+ return buf;
+ }
+
+#pragma CPROVER check pop
+
+ if (NULL == str) {
+ *buf = '\0';
+ return buf;
+ }
+
+ /* Free bytes needs to be one byte smaller than size of a storage,
+ * as strncpy always writes '\0', but doesn't include it in n
+ */
+ size_t bytes_to_copy = MIN(last - buf - 1, strlen(str));
+
+ char *p = buf;
+ if (bytes_to_copy > 0) {
+ p = (char *)memcpy(buf, str, bytes_to_copy) + bytes_to_copy;
+ }
+ *p = '\0';
+
+ return p;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_str.h b/contrib/restricted/aws/s2n/utils/s2n_str.h
index a0ca67c3ba..415891a274 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_str.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_str.h
@@ -1,17 +1,17 @@
-/*
- * 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.
- */
-#pragma once
-
-extern char *s2n_strcpy(char *buf, char *last, const char *str);
+/*
+ * 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.
+ */
+#pragma once
+
+extern char *s2n_strcpy(char *buf, char *last, const char *str);
diff --git a/contrib/restricted/aws/s2n/utils/s2n_timer.c b/contrib/restricted/aws/s2n/utils/s2n_timer.c
index e1766ce1e3..9a26278a4a 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_timer.c
+++ b/contrib/restricted/aws/s2n/utils/s2n_timer.c
@@ -1,49 +1,49 @@
-/*
- * 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 "utils/s2n_result.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_timer.h"
-
-#include "tls/s2n_config.h"
-
-S2N_RESULT s2n_timer_start(struct s2n_config *config, struct s2n_timer *timer)
-{
- GUARD_AS_RESULT(config->monotonic_clock(config->monotonic_clock_ctx, &timer->time));
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_timer_elapsed(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds)
-{
- uint64_t current_time;
-
- GUARD_AS_RESULT(config->monotonic_clock(config->monotonic_clock_ctx, &current_time));
-
- *nanoseconds = current_time - timer->time;
-
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_timer_reset(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds)
-{
- uint64_t previous_time = timer->time;
-
- GUARD_RESULT(s2n_timer_start(config, timer));
-
- *nanoseconds = timer->time - previous_time;
-
- return S2N_RESULT_OK;
-}
+/*
+ * 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 "utils/s2n_result.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_timer.h"
+
+#include "tls/s2n_config.h"
+
+S2N_RESULT s2n_timer_start(struct s2n_config *config, struct s2n_timer *timer)
+{
+ GUARD_AS_RESULT(config->monotonic_clock(config->monotonic_clock_ctx, &timer->time));
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_timer_elapsed(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds)
+{
+ uint64_t current_time;
+
+ GUARD_AS_RESULT(config->monotonic_clock(config->monotonic_clock_ctx, &current_time));
+
+ *nanoseconds = current_time - timer->time;
+
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_timer_reset(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds)
+{
+ uint64_t previous_time = timer->time;
+
+ GUARD_RESULT(s2n_timer_start(config, timer));
+
+ *nanoseconds = timer->time - previous_time;
+
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/utils/s2n_timer.h b/contrib/restricted/aws/s2n/utils/s2n_timer.h
index 8bd2b262c3..5532578720 100644
--- a/contrib/restricted/aws/s2n/utils/s2n_timer.h
+++ b/contrib/restricted/aws/s2n/utils/s2n_timer.h
@@ -1,27 +1,27 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include "utils/s2n_result.h"
-
-struct s2n_timer {
- uint64_t time;
-};
-
-extern S2N_RESULT s2n_timer_start(struct s2n_config *config, struct s2n_timer *timer);
-extern S2N_RESULT s2n_timer_elapsed(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds);
-extern S2N_RESULT s2n_timer_reset(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds);
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "utils/s2n_result.h"
+
+struct s2n_timer {
+ uint64_t time;
+};
+
+extern S2N_RESULT s2n_timer_start(struct s2n_config *config, struct s2n_timer *timer);
+extern S2N_RESULT s2n_timer_elapsed(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds);
+extern S2N_RESULT s2n_timer_reset(struct s2n_config *config, struct s2n_timer *timer, uint64_t * nanoseconds);