[Git][NTPsec/ntpsec][2026-06-drop-libaes-siv] 8 commits: Add reproducible-builds URL to PIVOT.h
Mark Atwood (@MarkAtwood)
gitlab at mg.gitlab.com
Mon Jun 22 05:04:25 UTC 2026
Mark Atwood pushed to branch 2026-06-drop-libaes-siv at NTPsec / ntpsec
Commits:
5f92400e by Hal Murray at 2026-06-17T19:14:06-07:00
Add reproducible-builds URL to PIVOT.h
- - - - -
0f431c17 by Hal Murray at 2026-06-17T20:48:34-07:00
Fix package name change in buildprep
Fedora:
python-unversioned-command-3 => python-unversioned-command
- - - - -
c7461cb7 by Hal Murray at 2026-06-17T23:38:02-07:00
Attempt to fix Alpine CI troubles
Python 3.12 => 3.14
- - - - -
2a487ab6 by Mark Atwood at 2026-06-21T22:03:53-07:00
build: require OpenSSL >= 3.0 (LibreSSL exempt)
Replace the narrow "reject only OpenSSL 1.1.1a" probe with a real version
floor: OpenSSL must be 3.0.0 or newer. The check still runs only in the
NTS path (gated by DISABLE_NTS), so distros that build --disable-nts are
unaffected.
LibreSSL is exempted: it reports OPENSSL_VERSION_NUMBER as 0x2000000fL but
remains a supported platform, so dropping it is left as a separate
decision. This bump does not yet enable removing the vendored libaes_siv.
Rename check_openssl_bad_version -> check_openssl_version accordingly.
- - - - -
9deb8ef1 by Mark Atwood at 2026-06-21T22:03:53-07:00
fix: update stale comment referencing libaes_siv
- - - - -
10afca57 by Mark Atwood at 2026-06-21T22:03:53-07:00
fix: correct OpenSSL version in comment (3.0+, not 3.2+)
- - - - -
7776730f by Mark Atwood at 2026-06-21T22:03:53-07:00
fix: guard OPENSSL_cleanse for NULL output in decrypt
- - - - -
b6c8aa9c by Mark Atwood at 2026-06-21T22:03:54-07:00
feat: replace libaes_siv with OpenSSL 3.x native AES-SIV
Remove the bundled libaes_siv library (~2400 LOC) and replace it with
a thin EVP wrapper (~285 LOC) using OpenSSL 3.x native AES-SIV.
OpenSSL 3.0+ provides AES-SIV via EVP_CIPHER, eliminating the need for
the bundled implementation. This simplifies the codebase and enables
future use of OpenSSL providers (e.g., wolfProvider for FIPS).
- Add include/aes_siv_evp.h: API-compatible header
- Add libntp/aes_siv_evp.c: EVP-based implementation
- Delete libaes_siv/: remove bundled library (14 files)
- Update wscripts: remove libaes_siv, add aes_siv_evp.c
- Update includes: aes_siv.h -> aes_siv_evp.h
- - - - -
27 changed files:
- .gitlab-ci.yml
- PIVOT.h
- buildprep
- + include/aes_siv_evp.h
- − libaes_siv/AES_SIV_CTX_new.adoc
- − libaes_siv/AES_SIV_Encrypt.adoc
- − libaes_siv/AES_SIV_Init.adoc
- − libaes_siv/COPYING
- − libaes_siv/External-Version.txt
- − libaes_siv/README.md
- − libaes_siv/aes_siv.c
- − libaes_siv/aes_siv.h
- − libaes_siv/aes_siv_test.c
- − libaes_siv/bench.c
- − libaes_siv/config.h.in
- − libaes_siv/demo.c
- − libaes_siv/tests.c
- − libaes_siv/wscript
- + libntp/aes_siv_evp.c
- libntp/wscript
- ntpd/nts_cookie.c
- ntpd/nts_extens.c
- ntpd/wscript
- tests/ntpd/nts_cookie.c
- tests/ntpd/nts_extens.c
- wafhelpers/openssl.py
- wscript
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -2,7 +2,7 @@ pages:
stage: build
image: $CI_REGISTRY/ntpsec/ntpsec/alpine-pages
script:
- - echo /tmp/docbot-local/lib/python3.12/site-packages > /usr/lib/python3.12/site-packages/ntpsec.pth
+ - echo /tmp/docbot-local/lib/python3.14/site-packages > /usr/lib/python3.14/site-packages/ntpsec.pth
- mkdir -p public/latest
- python3 ./waf configure --prefix=/tmp/docbot-local --htmldir=`pwd`/public/latest/ --enable-doc --disable-manpage build install
# tar to work around waf ignoring GNU dirs
@@ -47,7 +47,7 @@ alpine-basic:
<<: *job_definition
image: $CI_REGISTRY/ntpsec/ntpsec/alpine
script:
- - echo /usr/local/lib/python3.12/site-packages > /usr/lib/python3.12/site-packages/ntpsec.pth
+ - echo /usr/local/lib/python3.14/site-packages > /usr/lib/python3.14/site-packages/ntpsec.pth
- python3 ./waf configure --enable-warnings --enable-Werror --disable-doc --disable-manpage build --pyshebang "/usr/bin/env python3"
- python3 ./waf install
- python3 ./waf uninstall
=====================================
PIVOT.h
=====================================
@@ -4,6 +4,7 @@
/* We would like to use the build date.
* But that breaks repeatable builds.
+ * https://reproducible-builds.org/specs/source-date-epoch/
* Update this before each release.
* Some tests may need to be updated.
=====================================
buildprep
=====================================
@@ -232,7 +232,7 @@ daemon () {
yum|dnf)
$do $installer group install development-tools # Build environment
$install python3 python3-devel # build
- $install python-unversioned-command-3 # python => python3
+ $install python-unversioned-command # python => python3
$install bison openssl-devel # build
$install libcap-devel libseccomp-devel # build
$install pps-tools-devel # build
=====================================
include/aes_siv_evp.h
=====================================
@@ -0,0 +1,127 @@
+/*
+ * aes_siv_evp.h - AES-SIV wrapper using OpenSSL 3.x EVP
+ * Copyright the NTPsec project contributors
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This provides the same API as libaes_siv but uses OpenSSL 3.x native
+ * EVP_CIPHER AES-SIV support instead of the bundled libaes_siv library.
+ *
+ * API-compatible replacement for libaes_siv/aes_siv.h
+ */
+
+#ifndef AES_SIV_EVP_H_
+#define AES_SIV_EVP_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Opaque context structure for AES-SIV operations.
+ * The context can be reused for multiple encrypt/decrypt operations.
+ */
+typedef struct AES_SIV_CTX_st AES_SIV_CTX;
+
+/*
+ * Allocate and initialize a new AES-SIV context.
+ *
+ * Returns: pointer to new context on success, NULL on failure
+ */
+AES_SIV_CTX *AES_SIV_CTX_new(void);
+
+/*
+ * Free an AES-SIV context and securely clear any sensitive data.
+ *
+ * ctx: context to free (may be NULL)
+ */
+void AES_SIV_CTX_free(AES_SIV_CTX *ctx);
+
+/*
+ * Clean up a context for reuse without freeing it.
+ * Securely clears any sensitive data from the context.
+ *
+ * ctx: context to clean up
+ */
+void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx);
+
+/*
+ * Copy an AES-SIV context.
+ *
+ * dst: destination context (must be allocated)
+ * src: source context
+ *
+ * Returns: 1 on success, 0 on failure
+ */
+int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const *src);
+
+/*
+ * One-shot AES-SIV encryption.
+ *
+ * This function encrypts plaintext using AES-SIV mode (RFC 5297).
+ * The output consists of a 16-byte SIV tag followed by the ciphertext.
+ *
+ * ctx: AES-SIV context (used as scratch space)
+ * out: output buffer for tag + ciphertext
+ * out_len: [in] size of output buffer, [out] actual output length
+ * key: encryption key (32, 48, or 64 bytes)
+ * key_len: key length in bytes
+ * nonce: optional nonce (treated as additional AD)
+ * nonce_len: nonce length in bytes (may be 0)
+ * plaintext: data to encrypt
+ * plaintext_len: plaintext length in bytes
+ * ad: additional authenticated data
+ * ad_len: AD length in bytes
+ *
+ * Returns: 1 on success, 0 on failure
+ *
+ * Key length determines the SIV variant:
+ * 32 bytes -> AEAD_AES_SIV_CMAC_256 (AES-128)
+ * 48 bytes -> AEAD_AES_SIV_CMAC_384 (AES-192)
+ * 64 bytes -> AEAD_AES_SIV_CMAC_512 (AES-256)
+ */
+int AES_SIV_Encrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
+ unsigned char const *key, size_t key_len,
+ unsigned char const *nonce, size_t nonce_len,
+ unsigned char const *plaintext, size_t plaintext_len,
+ unsigned char const *ad, size_t ad_len);
+
+/*
+ * One-shot AES-SIV decryption.
+ *
+ * This function decrypts ciphertext encrypted with AES-SIV mode (RFC 5297).
+ * The input consists of a 16-byte SIV tag followed by the ciphertext.
+ * Decryption includes authentication; if authentication fails, the output
+ * is zeroed and the function returns 0.
+ *
+ * ctx: AES-SIV context (used as scratch space)
+ * out: output buffer for plaintext
+ * out_len: [in] size of output buffer, [out] actual output length
+ * key: encryption key (32, 48, or 64 bytes)
+ * key_len: key length in bytes
+ * nonce: optional nonce (treated as additional AD)
+ * nonce_len: nonce length in bytes (may be 0)
+ * ciphertext: tag + ciphertext to decrypt
+ * ciphertext_len: total ciphertext length (including 16-byte tag)
+ * ad: additional authenticated data
+ * ad_len: AD length in bytes
+ *
+ * Returns: 1 on success (authentication passed), 0 on failure
+ *
+ * Key length determines the SIV variant:
+ * 32 bytes -> AEAD_AES_SIV_CMAC_256 (AES-128)
+ * 48 bytes -> AEAD_AES_SIV_CMAC_384 (AES-192)
+ * 64 bytes -> AEAD_AES_SIV_CMAC_512 (AES-256)
+ */
+int AES_SIV_Decrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
+ unsigned char const *key, size_t key_len,
+ unsigned char const *nonce, size_t nonce_len,
+ unsigned char const *ciphertext, size_t ciphertext_len,
+ unsigned char const *ad, size_t ad_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AES_SIV_EVP_H_ */
=====================================
libaes_siv/AES_SIV_CTX_new.adoc deleted
=====================================
@@ -1,69 +0,0 @@
-AES_SIV_CTX_new(3)
-==================
-:doctype: manpage
-
-NAME
-----
-
-AES_SIV_CTX_new, AES_SIV_CTX_copy, AES_SIV_CTX_cleanup, AES_SIV_CTX_free - manage AES-SIV contexts
-
-SYNOPSIS
---------
-
-[source,c]
-----
-#include <aes_siv.h>
-
-typedef struct AES_SIV_CTX_st AES_SIV_CTX;
-
-AES_SIV_CTX* AES_SIV_CTX_new();
-int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const* src);
-void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx);
-void AES_SIV_CTX_free(AES_SIV_CTX *ctx);
-----
-
-DESCRIPTION
------------
-
-An *AES_SIV_CTX* is an opaque structure which holds context for
-AES-SIV operations. A single +AES_SIV_CTX+ may be allocated and used
-repeatedly for multiple operations, so long as it is only used for one
-operation at a time.
-
-The *AES_SIV_CTX_new()* function allocates and returns a new,
-uninitialized +AES_SIV_CTX+.
-
-The *AES_SIV_CTX_copy()* function copies the contents of _src_
-into _dst_.
-
-The *AES_SIV_CTX_cleanup()* function erases the contents of _ctx_,
-rendering it uninitialized but still allocated.
-
-The *AES_SIV_CTX_free()* function frees the memory associated with
-`ctx`.
-
-NOTES
------
-
-AES_SIV_CTX_new() and AES_SIV_CTX_free() are the only functions in
-libaes_siv which allocate or free heap memory. They do so by calling
-OPENSSL_malloc() and OPENSSL_free(), so they will make use of any
-custom allocators provided to OpenSSL via CRYPTO_set_mem_functions().
-
-AES_SIV_CTX_cleanup() will securely erase all heap data asociated with
-the AES_SIV_CTX. libaes_siv does not attempt to sanitize the stack
-since compiler behaviors such as register spilling make such attempts
-too unreliable to be worthwhile.
-
-RETURN VALUES
--------------
-
-*AES_SIV_CTX_new()* returns a pointer to the newly-allocated context
-structure on success, or NULL on failure.
-
-*AES_SIV_CTX_copy()* returns 1 on success, 0 on failure.
-
-SEE ALSO
---------
-
-*AES_SIV_Encrypt*(3), *AES_SIV_Init*(3), RFC 5297
=====================================
libaes_siv/AES_SIV_Encrypt.adoc deleted
=====================================
@@ -1,79 +0,0 @@
-AES_SIV_Encrypt(3)
-==================
-:doctype: manpage
-
-NAME
-----
-
-AES_SIV_Encrypt, AES_SIV_Decrypt - AES-SIV high-level interface
-
-SYNOPSIS
---------
-
-[source,c]
-----
-#include <aes_siv.h>
-
-int AES_SIV_Encrypt(AES_SIV_CTX *ctx,
- unsigned char *out, size_t *out_len,
- unsigned char const* key, size_t key_len,
- unsigned char const* nonce, size_t nonce_len,
- unsigned char const* plaintext, size_t plaintext_len,
- unsigned char const* ad, size_t ad_len);
-
-int AES_SIV_Decrypt(AES_SIV_CTX *ctx,
- unsigned char *out, size_t *out_len,
- unsigned char const* key, size_t key_len,
- unsigned char const* nonce, size_t nonce_len,
- unsigned char const* ciphertext, size_t ciphertext_len,
- unsigned char const* ad, size_t ad_len);
-----
-
-DESCRIPTION
------------
-
-These functions provide a high-level interface for AES-SIV encryption
-and decryption, complying with RFC 5297.
-
-*AES_SIV_Encrypt()* uses the provided _ctx_ to encrypt the provided
-_plaintext_ and associated data _ad_ using the provided _key_ and
-_nonce_, and outputs up to _*out_len_ bytes of ciphertext into the
-memory pointed to by _out_. It sets _*out_len_ to the actual output
-length, which will always be _plaintext_len_ + 16.
-
-*AES_SIV_Decrypt()* uses the provided _ctx_ to authenticate and
-decrypt the provided _ciphertext_ and associated data _ad_ using the
-provided _key_ and _nonce_, and outputs up to _*out_len_ bytes of
-plaintext into the memory pointed to by _out_. It sets _*out_len_ to
-the actual output length, which will always be _ciphertext_len_ - 16.
-
-_key_len_ is given in bytes and must be 32, 48, or 64.
-
-For deterministic encryption, the _nonce_ may be NULL; note that this
-is distinct from providing a zero-length nonce; see NOTES.
-
-NOTES
------
-
-The output of +AES_SIV_Encrypt()+ is formatted as a 16-byte
-authentication tag followed by the actual ciphertext. Plaintext may be
-encrypted in-place by letting _plaintext_ equal +&out[16]+. Similarly,
-ciphertext may be authenticated and decrypted in-place by letting
-_out_ equal +&ciphertext[16]+.
-
-RFC 5297 defines AES-SIV in such a way that deterministic use (i.e,
-not providing a nonce) is distinct from providing a nonce of zero
-length. The latter (a zero-length-onnce) is supported by libaes_siv
-but not recommended, and RFC 5297 is ambiguous as to whether it ought
-to be permitted: the operation is clearly defined, but the IANA
-registrations for AES-SIV's RFC 5116 interface specify an N_MIN of 1.
-
-RETURN VALUE
-------------
-
-These functions return 1 on success and 0 on failure.
-
-SEE ALSO
---------
-
-*AES_SIV_CTX_new*(3), *AES_SIV_Init*(3), RFC 5297
=====================================
libaes_siv/AES_SIV_Init.adoc deleted
=====================================
@@ -1,114 +0,0 @@
-AES_SIV_Init(3)
-===============
-:doctype: manpage
-
-NAME
-----
-
-AES_SIV_Init, AES_SIV_AssociateData, AES_SIV_EncryptFinal, AES_SIV_DecryptFinal - AES-SIV low-level interface
-
-SYNOPSIS
---------
-
-[source,c]
-----
-#include <aes_siv.h>
-
-int AES_SIV_Init(AES_SIV_CTX *ctx, unsigned char const* key, size_t key_len);
-int AES_SIV_AssociateData(AES_SIV_CTX *ctx, unsigned char const* data, size_t len);
-int AES_SIV_EncryptFinal(AES_SIV_CTX *ctx,
- unsigned char *v_out, unsigned char *c_out,
- unsigned char const* plaintext, size_t len);
-int AES_SIV_DecryptFinal(AES_SIV_CTX *ctx, unsigned char *out,
- unsigned char const* v, unsigned char const* c,
- size_t len);
-----
-
-DESCRIPTION
------------
-
-These functions provide a low-level interface for AES-SIV encryption
-and decryption, complying with RFC 5297.
-
-*AES_SIV_Init()* prepares _ctx_ for encrypting or decrypting data
-under the given _key_.
-
-*AES_SIV_AssociateData*() adds a block of associated data to *ctx*.
-This function is also used for adding a _nonce_; see NOTES for details.
-
-*AES_SIV_EncryptFinal()* encrypts the provided _plaintext_, writing a
-16-byte authentication tag to _v_out_ and ciphertext to _c_out_. The
-ciphertext written to _c_out_ will be equal in length to the
-plaintext, with both lengths given by _len_.
-
-*AES_SIV_DecryptFinal()* decrypts and verifies the provided ciphertext
-_c_ and 16-byte authentication tag _v_, writing plaintext to _out_.
-The plaintext will be equal in length to _c_, with both lengths
-given by _len_.
-
-RETURN VALUE
-------------
-
-These functions return 1 on success, 0 on failure.
-
-NOTES
------
-
-When encrypting or decrypting/authenticating multiple messages under
-the same key, these functions may be used to achieve better
-performance than is possible using the high-level API by caching the
-result of of key setup. After calling +AES_SIV_Init+(), retain the
-resulting _ctx_ structure and use +AES_SIV_CTX_copy+() to make a copy
-of it for each message being encrypted or decrypted.
-
-The arguments to a typical AEAD encryption function consist of a key,
-a nonce, associated data, and plaintext. However, RFC 5297 defines
-AES-SIV as accepting an arbitrary number of associated data arguments,
-and specifies that the nonce should be given as the final such
-argument. This low-level API is structured accordingly. The
-high-level functions +AES_SIV_Encrypt+() and +AES_SIV_Decrypt+() are
-implemented on top of it approximately as follows; error-handling is
-omitted for brevity.
-
-[source,c]
-----
-int AES_SIV_Encrypt(AES_SIV_CTX *ctx,
- unsigned char *out, size_t *out_len,
- unsigned char const* key, size_t key_len,
- unsigned char const* nonce, size_t nonce_len,
- unsigned char const* plaintext, size_t plaintext_len,
- unsigned char const *ad, size_t ad_len) {
- *out_len = plaintext_len + 16;
-
- /* Do not copy-paste this code; it is missing return-value
- checking.*/
- AES_SIV_Init(ctx, key, key_len);
- AES_SIV_AssociateData(ctx, ad, ad_len;
- if(nonce) AES_SIV_AssociateData(ctx, nonce, nonce_len);
- AES_SIV_EncryptFinal(ctx, out, out+16, plaintext, plaintext_len);
- return 1;
-}
-
-int AES_SIV_Decrypt(AES_SIV_CTX *ctx,
- unsigned char *out, size_t *out_len,
- unsigned char const* key, size_t key_len,
- unsigned char const* nonce, size_t nonce_len,
- unsigned char const* ciphertext, size_t ciphertext_len,
- unsigned char const *ad, size_t ad_len) {
- *out_len = ciphertext_len - 16;
-
- /* Do not copy-paste this code; it is missing return-value
- checking.*/
- AES_SIV_Init(ctx, key, key_len);
- AES_SIV_AssociateData(ctx, ad, ad_len);
- if(nonce) AES_SIV_AssociateData(ctx, nonce, nonce_len);
- AES_SIV_DecryptFinal(ctx, out, ciphertext, ciphertext + 16,
- ciphertext_len - 16);
- return 1;
-}
-----
-
-SEE ALSO
---------
-
-*AES_SIV_CTX_new*(3), *AES_SIV_Encrypt*(3), RFC 5297
=====================================
libaes_siv/COPYING deleted
=====================================
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
=====================================
libaes_siv/External-Version.txt deleted
=====================================
@@ -1,4 +0,0 @@
-Upstream Source: https://github.com/dfoxfranke/libaes_siv
-Description: An RFC5297-compliant C implementation of AES-SIV
-Synchronised on: 2021-02-11
-Synchronised at: 9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b
=====================================
libaes_siv/README.md deleted
=====================================
@@ -1,197 +0,0 @@
-# libaes_siv
-
-This is an [RFC5297](https://tools.ietf.org/html/rfc5297)-compliant C
-implementation of AES-SIV written by Daniel Franke on behalf of
-[Akamai Technologies](https://www.akamai.com). It is published under
-the [Apache License
-(v2.0)](https://www.apache.org/licenses/LICENSE-2.0). It uses OpenSSL
-for the underlying
-[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) and
-[CMAC](https://en.wikipedia.org/wiki/One-key_MAC) implementations and
-follows a similar interface style.
-
-An AES_SIV implementation forked from libaes_siv has been [merged into
-the OpenSSL master branch](https://github.com/openssl/openssl/pull/3540).
-However, the two implementations are not API-compatible; see section
-"OpenSSL API Comparison" below.
-
-## Overview of SIV mode
-
-Synthetic Initialization Vector (SIV) mode is a [block cipher mode of
-operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
-for [authenticated encryption with associated
-data](https://en.wikipedia.org/wiki/Authenticated_encryption) designed
-to be maximally resistant to accidental
-[nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) reuse. If
-two messages are accidentally encrypted using the same nonce and the
-same associated data, the attacker learns nothing except whether or
-not the plaintexts of the two messages are identical to each other.
-SIV mode also permits the nonce to be intentionally omitted, resulting
-in a [deterministic encryption
-scheme](https://en.wikipedia.org/wiki/Deterministic_encryption).
-
-Here are a couple common situations where AES-SIV may be an
-appropriate choice of AEAD scheme:
-
-1. You can't count on the system doing the encrypting to reliably
- generate a unique nonce for every message. For example, the system
- may be an embedded device with no good entropy source, or may be a
- VM subject to be snapshotted and restored.
-
-2. You want your encryption to be deterministic so that an
- intermediating party such as a caching proxy, provided only with
- ciphertext, can perform deduplication.
-
-The drawback to SIV mode is that it requires two passes over its
-input. This makes it potentially clumsy for use with large messages
-since the entire message must be held in memory at one time. SIV mode
-is also a bit slower than most widely-used block cipher modes (but
-can still be quite fast — see performance numbers below).
-
-Be aware that with *any* encryption scheme, including SIV, repeating
-or omitting a nonce can still be [fatal to
-security](https://xkcd.com/257) if your plaintexts have low entropy,
-e.g., if each message consists only of a single bit.
-
-Keys for SIV mode are twice the length of the keys for the underlying
-block cipher. For example, keys for AES-128-SIV are 256 bits long,
-and keys for AES-256-SIV are 512 bits long.
-
-## Build instructions
-
-Build dependencies:
-
-* Any ISO C89 compiler (GCC or Clang recommended). No C99 language
- features are required, however `<stdint.h>` must be available and
- must define `uint64_t`. `char` must be 8 bits and arithmetic must be
- two's complement.
-* [CMake](https://cmake.org) >= 3.1
-* [OpenSSL](https://openssl.org) >=1.0.1 (libcrypto only). A recent
- release from the 1.0.2 branch or later is strongly recommended since
- 1.0.1 was EOL'ed at the end of 2016. Furthermore, OpenSSL versions prior
- to 1.0.1n and 1.0.2b have known bugs which impact `libaes_siv` and
- will cause failures in its test suite. LibreSSL is not supported.
-* [Asciidoc](http://asciidoc.org) (only required for building man pages)
-
-Running benchmarks requires a POSIX.1-2001 compliant OS, including
-the `clock_gettime` system call.
-
-To build and install on POSIX-like platforms:
-```
- cmake . &&
- make &&
- make test &&
- sudo make install
-```
-
-NOTE: Out-of-source builds are allowed, but out-of-source manpage builds
-require a2x's -D option, which may provoke an apparently bogus warning from a2x.
-
-If you want to build on an OS X machine, install the Xcode development
-environment and the command line tools, then use either the Homebrew package
-manager or the MacPorts package manager to install cmake and OpenSSL.
-
-Homebrew (https://brew.sh/):
-```
- brew install cmake openssl &&
- cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/openssl . &&
- make &&
- make test &&
- sudo make install
-```
-MacPorts (https://www.macports.org/):
-```
- sudo port install cmake openssl &&
- cmake . &&
- make &&
- make test &&
- sudo make install
-```
-
-To create a native Windows build, you will first need to build
-OpenSSL. Install Visual Studio, CMake, ActiveState Perl, and NASM, and
-ensure that `nasm.exe` is somewhere in your `%PATH%`. From a VS developer
-command prompt, unpack the OpenSSL sources and run
-```
- perl Configure VC-WIN64A
- nmake
-```
-Then to build `libaes_siv`, run
-```
- cmake -G "NMake Makefiles" -DOPENSSL_ROOT_DIR=\path\to\openssl .
- nmake
- nmake test
-```
-
-## Usage
-
-See the manual pages for API documentation, and the test vectors
-in `tests.c` for simple usage examples. You can also use the `demo` command
-line program to encrypt and decrypt data.
-
-## OpenSSL API Comparison
-
-In December 2018, OpenSSL merged an AES-SIV implementation derived
-from libaes_siv. As of February 2019 this implementation has not been
-released yet; it will appear some time post-1.1.1. However, despite
-the two implementations' common ancestry, they are not API-compatible.
-The OpenSSL team had to make an ugly-but-necessary compromise in order
-to shoehorn SIV mode into OpenSSL's EVP API, which is a streaming API
-that was never designed to support SIV's two-pass operation. When used for
-SIV operations, the EVP API is forced to return an error if you invoke
-`EVP_(En|De)crypt_Update` more than once for the same message.
-
-When designing libaes_siv, I rejected this behavior as an unacceptable
-breakdown of the API contract and opted to dispense with the EVP
-abstraction altogether rather than permit it to leak. libaes_siv's API
-remains stylistically similar to EVP, but is nonetheless distinct and
-avoids the above pitfall.
-
-## Performance
-
-On the author's Intel Core i7-6560U laptop, libaes_siv can process
-approximately 796 MiB of plaintext or ciphertext or 963 MiB of
-associated data per second using 256-bit keys
-(i.e., AES-128). Encrypting a zero-byte message takes approximately
-990ns. To obtain numbers for your own system, run `make bench &&
-./bench`.
-
-## Software assurance
-
-libaes_siv's test suite includes all test vectors from RFC 5297 and
-achieves 100% code coverage according to
-[gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html). It produces
-clean output from [Valgrind](https://valgrind.org) and from Clang's
-[undefined behavior
-sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
-and is verified using [ctgrind](https://github.com/agl/ctgrind) to run
-in constant time.
-
-Nonetheless, libaes_siv should at present be considered beta-quality
-code. It has not yet been tested on platforms other than x86-64 Linux
-or benefited from any significant amount of user feedback, and
-the codebase is in need of additional review by cryptographers and
-expert C programmers.
-
-## Bugs and pull requests
-
-Use the GitHub issue tracker. For reporting sensitive security issues,
-contact the author directly. (Note: I no longer use PGP. Please
-request my Signal details if necessary).
-
-## A note on version numbers
-
-libaes_siv version numbers are of the form `<major>.<minor>.<patch>`
-and follow a semantic versioning scheme. The major version number
-will be incremented with any backward-incompatible ABI change. The
-minor version number will be incremented if new functionality is
-added without impacting ABI backward-compatibility. The patch
-version number will be incremented for releases that make no
-externally-visible changes.
-
-As a result of this scheme, on ELF platforms, the .so version will
-be the same as the release version.
-
-Version numbers indicate nothing about code quality or maturity. No
-code known or suspected to be less suitable for production use than
-previous releases will ever be tagged with a version number.
=====================================
libaes_siv/aes_siv.c deleted
=====================================
@@ -1,598 +0,0 @@
-/* Copyright Akamai Technologies, Inc.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/* Hack to supress a blizzard of warnings when built on OpenSSL 3
- * Drop this patch when upstream is fixed. */
-#define OPENSSL_SUPPRESS_DEPRECATED 1
-
-#define _POSIX_C_SOURCE 200112L
-#define _ISOC99_SOURCE 1
-
-#include "config.h"
-#include "aes_siv.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
-#ifdef ENABLE_DEBUG_OUTPUT
-#include <stdio.h>
-#endif
-#ifdef _MSC_VER
-/* For _byteswap_uint64 */
-#include <stdlib.h>
-#endif
-#include <string.h>
-
-#include <openssl/cmac.h>
-#include <openssl/crypto.h>
-#include <openssl/evp.h>
-
-#ifdef ENABLE_CTGRIND
-#include <ctgrind.h>
-#endif
-
-#if CHAR_BIT != 8
-#error "libaes_siv requires an 8-bit char type"
-#endif
-
-#if -1 != ~0
-#error "libaes_siv requires a two's-complement architecture"
-#endif
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901
-#undef inline
-#elif defined(__GNUC__) || defined(__clang__)
-#define inline __inline__
-#elif defined(_MSC_VER)
-#define inline __inline
-#else
-#define inline
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-#define LIKELY(cond) __builtin_expect(cond, 1)
-#define UNLIKELY(cond) __builtin_expect(cond, 0)
-#else
-#define LIKELY(cond) cond
-#define UNLIKELY(cond) cond
-#endif
-
-#ifndef ENABLE_CTGRIND
-static inline void ct_poison(const void *data, size_t len) {
- (void)data;
- (void)len;
-}
-static inline void ct_unpoison(const void *data, size_t len) {
- (void)data;
- (void)len;
-}
-#endif
-
-static void debug(const char *label, const unsigned char *hex, size_t len) {
-/* ENABLE_CTGRIND has to override ENABLE_DEBUG_OUTPUT since sensitive data
- gets printed.
-*/
-#if defined(ENABLE_DEBUG_OUTPUT) && !defined(ENABLE_CTGRIND)
- size_t i;
- printf("%16s: ", label);
- for (i = 0; i < len; i++) {
- if (i > 0 && i % 16 == 0) {
- printf("\n ");
- }
- printf("%.2x", (unsigned int)hex[i]);
- if (i > 0 && i % 4 == 3) {
- printf(" ");
- }
- }
- printf("\n");
-#else
- (void)label;
- (void)hex;
- (void)len;
-#endif
-}
-
-typedef union block_un {
- uint64_t word[2];
- unsigned char byte[16];
-} block;
-
-const union {
- uint64_t word;
- char byte[8];
-} endian = {0x0102030405060708};
-
-#define I_AM_BIG_ENDIAN (endian.byte[0] == 1 && \
- endian.byte[1] == 2 && \
- endian.byte[2] == 3 && \
- endian.byte[3] == 4 && \
- endian.byte[4] == 5 && \
- endian.byte[5] == 6 && \
- endian.byte[6] == 7 && \
- endian.byte[7] == 8)
-
-#define I_AM_LITTLE_ENDIAN (endian.byte[0] == 8 && \
- endian.byte[1] == 7 && \
- endian.byte[2] == 6 && \
- endian.byte[3] == 5 && \
- endian.byte[4] == 4 && \
- endian.byte[5] == 3 && \
- endian.byte[6] == 2 && \
- endian.byte[7] == 1)
-
-#if defined(__GNUC__) || defined(__clang__)
-static inline uint64_t bswap64(uint64_t x) { return __builtin_bswap64(x); }
-#elif defined(_MSC_VER)
-static inline uint64_t bswap64(uint64_t x) { return _byteswap_uint64(x); }
-#else
-
-static inline uint32_t rotl(uint32_t x) { return (x << 8) | (x >> 24); }
-static inline uint32_t rotr(uint32_t x) { return (x >> 8) | (x << 24); }
-
-static inline uint64_t bswap64(uint64_t x) {
- uint32_t high = (uint32_t)(x >> 32);
- uint32_t low = (uint32_t)x;
-
- high = (rotl(high) & 0x00ff00ff) | (rotr(high) & 0xff00ff00);
- low = (rotl(low) & 0x00ff00ff) | (rotr(low) & 0xff00ff00);
- return ((uint64_t)low) << 32 | (uint64_t)high;
-}
-#endif
-
-static inline uint64_t getword(block const *block, size_t i) {
-#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
- if (I_AM_BIG_ENDIAN) {
- return block->word[i];
- } else if (I_AM_LITTLE_ENDIAN) {
- return bswap64(block->word[i]);
- } else {
-#endif
- i <<= 3;
- return ((uint64_t)block->byte[i + 7]) |
- ((uint64_t)block->byte[i + 6] << 8) |
- ((uint64_t)block->byte[i + 5] << 16) |
- ((uint64_t)block->byte[i + 4] << 24) |
- ((uint64_t)block->byte[i + 3] << 32) |
- ((uint64_t)block->byte[i + 2] << 40) |
- ((uint64_t)block->byte[i + 1] << 48) |
- ((uint64_t)block->byte[i] << 56);
-#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
- }
-#endif
-}
-
-static inline void putword(block *block, size_t i, uint64_t x) {
-#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
- if (I_AM_BIG_ENDIAN) {
- block->word[i] = x;
- } else if (I_AM_LITTLE_ENDIAN) {
- block->word[i] = bswap64(x);
- } else {
-#endif
- i <<= 3;
- block->byte[i] = (unsigned char)(x >> 56);
- block->byte[i + 1] = (unsigned char)((x >> 48) & 0xff);
- block->byte[i + 2] = (unsigned char)((x >> 40) & 0xff);
- block->byte[i + 3] = (unsigned char)((x >> 32) & 0xff);
- block->byte[i + 4] = (unsigned char)((x >> 24) & 0xff);
- block->byte[i + 5] = (unsigned char)((x >> 16) & 0xff);
- block->byte[i + 6] = (unsigned char)((x >> 8) & 0xff);
- block->byte[i + 7] = (unsigned char)(x & 0xff);
-#ifndef ENABLE_DEBUG_WEIRD_ENDIAN
- }
-#endif
-}
-
-static inline void xorblock(block *x, block const *y) {
- x->word[0] ^= y->word[0];
- x->word[1] ^= y->word[1];
-}
-
-/* Doubles `block`, which is 16 bytes representing an element
- of GF(2**128) modulo the irreducible polynomial
- x**128 + x**7 + x**2 + x + 1. */
-static inline void dbl(block *block) {
- uint64_t high = getword(block, 0);
- uint64_t low = getword(block, 1);
- uint64_t high_carry = high & (((uint64_t)1) << 63);
- uint64_t low_carry = low & (((uint64_t)1) << 63);
- /* Assumes two's-complement arithmetic */
- int64_t low_mask = -((int64_t)(high_carry >> 63)) & 0x87;
- uint64_t high_mask = low_carry >> 63;
- high = (high << 1) | high_mask;
- low = (low << 1) ^ (uint64_t)low_mask;
- putword(block, 0, high);
- putword(block, 1, low);
-}
-
-struct AES_SIV_CTX_st {
- /* d stores intermediate results of S2V; it corresponds to D from the
- pseudocode in section 2.4 of RFC 5297. */
- block d;
- EVP_CIPHER_CTX *cipher_ctx;
- /* SIV_AES_Init() sets up cmac_ctx_init. cmac_ctx is a scratchpad used
- by SIV_AES_AssociateData() and SIV_AES_(En|De)cryptFinal. */
- CMAC_CTX *cmac_ctx_init, *cmac_ctx;
-};
-
-void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx) {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- EVP_CIPHER_CTX_reset(ctx->cipher_ctx);
-#else
- EVP_CIPHER_CTX_cleanup(ctx->cipher_ctx);
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER <= 0x10100060L
- /* Workaround for an OpenSSL bug that causes a double free
- if you call CMAC_CTX_cleanup() before CMAC_CTX_free().
- https://github.com/openssl/openssl/pull/2798
- */
- CMAC_CTX_free(ctx->cmac_ctx_init);
- ctx->cmac_ctx_init = CMAC_CTX_new();
- CMAC_CTX_free(ctx->cmac_ctx);
- ctx->cmac_ctx = CMAC_CTX_new();
-#else
- CMAC_CTX_cleanup(ctx->cmac_ctx_init);
- CMAC_CTX_cleanup(ctx->cmac_ctx);
-#endif
- OPENSSL_cleanse(&ctx->d, sizeof ctx->d);
-}
-
-void AES_SIV_CTX_free(AES_SIV_CTX *ctx) {
- if (ctx) {
- EVP_CIPHER_CTX_free(ctx->cipher_ctx);
- /* Prior to OpenSSL 1.0.2b, CMAC_CTX_free() crashes on NULL */
- if (LIKELY(ctx->cmac_ctx_init != NULL)) {
- CMAC_CTX_free(ctx->cmac_ctx_init);
- }
- if (LIKELY(ctx->cmac_ctx != NULL)) {
- CMAC_CTX_free(ctx->cmac_ctx);
- }
- OPENSSL_cleanse(&ctx->d, sizeof ctx->d);
- OPENSSL_free(ctx);
- }
-}
-
-AES_SIV_CTX *AES_SIV_CTX_new(void) {
- AES_SIV_CTX *ctx = OPENSSL_malloc(sizeof(struct AES_SIV_CTX_st));
- if (UNLIKELY(ctx == NULL)) {
- return NULL;
- }
-
- ctx->cipher_ctx = EVP_CIPHER_CTX_new();
- ctx->cmac_ctx_init = CMAC_CTX_new();
- ctx->cmac_ctx = CMAC_CTX_new();
-
- if (UNLIKELY(ctx->cipher_ctx == NULL ||
- ctx->cmac_ctx_init == NULL ||
- ctx->cmac_ctx == NULL)) {
- AES_SIV_CTX_free(ctx);
- return NULL;
- }
-
- return ctx;
-}
-
-int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const *src) {
- memcpy(&dst->d, &src->d, sizeof src->d);
- if(UNLIKELY(EVP_CIPHER_CTX_copy(dst->cipher_ctx, src->cipher_ctx)
- != 1)) {
- return 0;
- }
- if (UNLIKELY(CMAC_CTX_copy(dst->cmac_ctx_init, src->cmac_ctx_init)
- != 1)) {
- return 0;
- }
- /* Not necessary to copy cmac_ctx since it's just temporary
- * storage */
- return 1;
-}
-
-int AES_SIV_Init(AES_SIV_CTX *ctx, unsigned char const *key, size_t key_len) {
- static const unsigned char zero[] = {0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0};
- size_t out_len;
- int ret = 0;
-
- ct_poison(key, key_len);
-
- switch (key_len) {
- case 32:
- if (UNLIKELY(CMAC_Init(ctx->cmac_ctx_init, key, 16,
- EVP_aes_128_cbc(), NULL) != 1)) {
- goto done;
- }
- if (UNLIKELY(EVP_EncryptInit_ex(ctx->cipher_ctx,
- EVP_aes_128_ctr(),
- NULL, key + 16, NULL) != 1)) {
- goto done;
- }
- break;
- case 48:
- if (UNLIKELY(CMAC_Init(ctx->cmac_ctx_init, key, 24,
- EVP_aes_192_cbc(), NULL) != 1)) {
- goto done;
- }
- if (UNLIKELY(EVP_EncryptInit_ex(ctx->cipher_ctx,
- EVP_aes_192_ctr(),
- NULL, key + 24, NULL) != 1)) {
- goto done;
- }
- break;
- case 64:
- if (UNLIKELY(CMAC_Init(ctx->cmac_ctx_init, key, 32,
- EVP_aes_256_cbc(), NULL) != 1)) {
- goto done;
- }
- if (UNLIKELY(EVP_EncryptInit_ex(ctx->cipher_ctx,
- EVP_aes_256_ctr(),
- NULL, key + 32, NULL) != 1)) {
- goto done;
- }
- break;
- default:
- goto done;
- }
-
- if (UNLIKELY(CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init) != 1)) {
- goto done;
- }
- if (UNLIKELY(CMAC_Update(ctx->cmac_ctx, zero, sizeof zero) != 1)) {
- goto done;
- }
- out_len = sizeof ctx->d;
- if (UNLIKELY(CMAC_Final(ctx->cmac_ctx, ctx->d.byte, &out_len) != 1)) {
- goto done;
- }
- debug("CMAC(zero)", ctx->d.byte, out_len);
- ret = 1;
-
- done:
- ct_unpoison(key, key_len);
- return ret;
-}
-
-int AES_SIV_AssociateData(AES_SIV_CTX *ctx, unsigned char const *data,
- size_t len) {
- block cmac_out;
- size_t out_len = sizeof cmac_out;
- int ret = 0;
-
- ct_poison(data, len);
-
- dbl(&ctx->d);
- debug("double()", ctx->d.byte, 16);
-
- if (UNLIKELY(CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init) != 1)) {
- goto done;
- }
- if (UNLIKELY(CMAC_Update(ctx->cmac_ctx, data, len) != 1)) {
- goto done;
- }
- if (UNLIKELY(CMAC_Final(ctx->cmac_ctx, cmac_out.byte, &out_len) != 1)) {
- goto done;
- }
- assert(out_len == 16);
- debug("CMAC(ad)", cmac_out.byte, 16);
-
- xorblock(&ctx->d, &cmac_out);
- debug("xor", ctx->d.byte, 16);
- ret = 1;
-
-done:
- ct_unpoison(data, len);
- return ret;
-}
-
-static inline int do_s2v_p(AES_SIV_CTX *ctx, block *out,
- unsigned char const* in, size_t len) {
- block t;
- size_t out_len = sizeof out->byte;
-
- if (UNLIKELY(CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init) != 1)) {
- return 0;
- }
-
- if(len >= 16) {
- if(UNLIKELY(CMAC_Update(ctx->cmac_ctx, in, len - 16) != 1)) {
- return 0;
- }
- debug("xorend part 1", in, len - 16);
- memcpy(&t, in + (len-16), 16);
- xorblock(&t, &ctx->d);
- debug("xorend part 2", t.byte, 16);
- if(UNLIKELY(CMAC_Update(ctx->cmac_ctx, t.byte, 16) != 1)) {
- return 0;
- }
- } else {
- size_t i;
- memcpy(&t, in, len);
- t.byte[len] = 0x80;
- for(i = len + 1; i < 16; i++) {
- t.byte[i] = 0;
- }
- debug("pad", t.byte, 16);
- dbl(&ctx->d);
- xorblock(&t, &ctx->d);
- debug("xor", t.byte, 16);
- if(UNLIKELY(CMAC_Update(ctx->cmac_ctx, t.byte, 16) != 1)) {
- return 0;
- }
- }
- if(UNLIKELY(CMAC_Final(ctx->cmac_ctx, out->byte, &out_len) != 1)) {
- return 0;
- }
- assert(out_len == 16);
- debug("CMAC(final)", out->byte, 16);
- return 1;
-}
-
-static inline int do_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out,
- unsigned char const *in, size_t len, block *icv) {
-#ifdef ENABLE_DEBUG_TINY_CHUNK_SIZE
- const int chunk_size = 7;
-#else
- const int chunk_size = 1 << 30;
-#endif
- size_t len_remaining = len;
- int out_len;
- int ret;
-
- if(UNLIKELY(EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, icv->byte)
- != 1)) {
- return 0;
- }
-
- while(UNLIKELY(len_remaining > (size_t)chunk_size)) {
- out_len = chunk_size;
- if(UNLIKELY(EVP_EncryptUpdate(ctx, out, &out_len, in, out_len)
- != 1)) {
- return 0;
- }
- assert(out_len == chunk_size);
- out += out_len;
- in += out_len;
- len_remaining -= (size_t)out_len;
- }
-
- out_len = (int)len_remaining;
- ret = EVP_EncryptUpdate(ctx, out, &out_len, in, out_len);
- assert(!ret || out_len == (int)len_remaining);
- return ret;
-}
-
-int AES_SIV_EncryptFinal(AES_SIV_CTX *ctx, unsigned char *v_out,
- unsigned char *c_out, unsigned char const *plaintext,
- size_t len) {
- block q;
- int ret = 0;
-
- ct_poison(plaintext, len);
-
- if(UNLIKELY(do_s2v_p(ctx, &q, plaintext, len) != 1)) {
- goto done;
- }
-
- ct_unpoison(&q, sizeof q);
- memcpy(v_out, &q, 16);
- q.byte[8] &= 0x7f;
- q.byte[12] &= 0x7f;
-
- if(UNLIKELY(do_encrypt(ctx->cipher_ctx, c_out, plaintext, len, &q)
- != 1)) {
- goto done;
- }
-
- ret = 1;
- debug("ciphertext", c_out, len);
-
-done:
- ct_unpoison(plaintext, len);
- ct_unpoison(c_out, len);
- ct_unpoison(v_out, 16);
- return ret;
-}
-
-int AES_SIV_DecryptFinal(AES_SIV_CTX *ctx, unsigned char *out,
- unsigned char const *v, unsigned char const *c,
- size_t len) {
- block t, q;
- size_t i;
- uint64_t result;
- int ret = 0;
-
- ct_poison(c, len);
-
- memcpy(&q, v, 16);
- q.byte[8] &= 0x7f;
- q.byte[12] &= 0x7f;
-
- if(UNLIKELY(do_encrypt(ctx->cipher_ctx, out, c, len, &q) != 1)) {
- goto done;
- }
- debug("plaintext", out, len);
-
- if(UNLIKELY(do_s2v_p(ctx, &t, out, len) != 1)) {
- goto done;
- }
-
- for (i = 0; i < 16; i++) {
- t.byte[i] ^= v[i];
- }
-
- result = t.word[0] | t.word[1];
- ct_unpoison(&result, sizeof result);
- ret = !result;
-
- if(ret) {
- ct_unpoison(out, len);
- } else {
- OPENSSL_cleanse(out, len);
- }
-
-done:
- ct_unpoison(c, len);
- return ret;
-}
-
-int AES_SIV_Encrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
- unsigned char const *key, size_t key_len,
- unsigned char const *nonce, size_t nonce_len,
- unsigned char const *plaintext, size_t plaintext_len,
- unsigned char const *ad, size_t ad_len) {
- if (UNLIKELY(*out_len < plaintext_len + 16)) {
- return 0;
- }
- *out_len = plaintext_len + 16;
-
- if (UNLIKELY(AES_SIV_Init(ctx, key, key_len) != 1)) {
- return 0;
- }
- if (UNLIKELY(AES_SIV_AssociateData(ctx, ad, ad_len) != 1)) {
- return 0;
- }
- if (nonce != NULL &&
- UNLIKELY(AES_SIV_AssociateData(ctx, nonce, nonce_len) != 1)) {
- return 0;
- }
- if (UNLIKELY(AES_SIV_EncryptFinal(ctx, out, out + 16, plaintext,
- plaintext_len) != 1)) {
- return 0;
- }
-
- debug("IV || C", out, *out_len);
- return 1;
-}
-
-int AES_SIV_Decrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
- unsigned char const *key, size_t key_len,
- unsigned char const *nonce, size_t nonce_len,
- unsigned char const *ciphertext, size_t ciphertext_len,
- unsigned char const *ad, size_t ad_len) {
- if (UNLIKELY(ciphertext_len < 16)) {
- return 0;
- }
- if (UNLIKELY(*out_len < ciphertext_len - 16)) {
- return 0;
- }
- *out_len = ciphertext_len - 16;
-
- if (UNLIKELY(AES_SIV_Init(ctx, key, key_len) != 1)) {
- return 0;
- }
- if (UNLIKELY(AES_SIV_AssociateData(ctx, ad, ad_len) != 1)) {
- return 0;
- }
- if (nonce != NULL &&
- UNLIKELY(AES_SIV_AssociateData(ctx, nonce, nonce_len) != 1)) {
- return 0;
- }
- if (UNLIKELY(AES_SIV_DecryptFinal(ctx, out, ciphertext, ciphertext + 16,
- ciphertext_len - 16) != 1)) {
- return 0;
- }
- debug("plaintext", out, *out_len);
- return 1;
-}
=====================================
libaes_siv/aes_siv.h deleted
=====================================
@@ -1,57 +0,0 @@
-/* Copyright Akamai Technologies, Inc.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-#ifndef AES_SIV_H_
-#define AES_SIV_H_
-
-#include <stddef.h>
-
-#define LIBAES_SIV_VERSION_MAJOR 1
-#define LIBAES_SIV_VERSION_MINOR 0
-#define LIBAES_SIV_VERSION_PATCH 1
-
-#define LIBAES_SIV_VERSION ((LIBAES_SIV_VERSION_MAJOR << 16) + \
- (LIBAES_SIV_VERSION_MINOR << 8) + \
- LIBAES_SIV_VERSION_PATCH)
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct AES_SIV_CTX_st AES_SIV_CTX;
-
-AES_SIV_CTX *AES_SIV_CTX_new(void);
-int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const *src);
-void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx);
-void AES_SIV_CTX_free(AES_SIV_CTX *ctx);
-
-int AES_SIV_Init(AES_SIV_CTX *ctx, unsigned char const *key, size_t key_len);
-int AES_SIV_AssociateData(AES_SIV_CTX *ctx, unsigned char const *data,
- size_t len);
-int AES_SIV_EncryptFinal(AES_SIV_CTX *ctx, unsigned char *v_out,
- unsigned char *c_out, unsigned char const *plaintext,
- size_t len);
-int AES_SIV_DecryptFinal(AES_SIV_CTX *ctx, unsigned char *out,
- unsigned char const *v, unsigned char const *c,
- size_t len);
-
-int AES_SIV_Encrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
- unsigned char const *key, size_t key_len,
- unsigned char const *nonce, size_t nonce_len,
- unsigned char const *plaintext, size_t plaintext_len,
- unsigned char const *ad, size_t ad_len);
-
-int AES_SIV_Decrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
- unsigned char const *key, size_t key_len,
- unsigned char const *nonce, size_t nonce_len,
- unsigned char const *ciphertext, size_t ciphertext_len,
- unsigned char const *ad, size_t ad_len);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
=====================================
libaes_siv/aes_siv_test.c deleted
=====================================
@@ -1,3 +0,0 @@
-#define ENABLE_DEBUG_OUTPUT 1
-#undef NDEBUG
-#include "aes_siv.c"
=====================================
libaes_siv/bench.c deleted
=====================================
@@ -1,185 +0,0 @@
-/* Copyright Akamai Technologies, Inc.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-#include "config.h"
-#include "aes_siv.h"
-
-#define _POSIX_C_SOURCE 200112L
-
-#include <math.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-static const unsigned char key[64];
-static const unsigned char ad[65536];
-static const unsigned char nonce[16];
-static unsigned char in[65536+16];
-static unsigned char out[65536+16];
-
-static const struct {
- size_t key_len;
- size_t nonce_len;
- size_t in_len;
- size_t ad_len;
-} call_list[] = {
- { 32, 0, 0, 0 },
- { 32, 0, 65536, 0 },
- { 32, 0, 0, 65536 },
- { 32, 0, 65536, 65536 },
- { 32, 0, 1536, 0 },
- { 32, 0, 0, 1536 },
- { 32, 0, 1536, 1536 },
- { 32, 0, 64, 0},
- { 32, 0, 0, 64},
- { 32, 0, 64, 64},
- { 32, 16, 0, 0 },
- { 32, 16, 65536, 0 },
- { 32, 16, 0, 65536 },
- { 32, 16, 65536, 65536 },
- { 32, 16, 1536, 0 },
- { 32, 16, 0, 1536 },
- { 32, 16, 1536, 1536 },
- { 32, 16, 64, 0},
- { 32, 16, 0, 64},
- { 32, 16, 64, 64},
-
- { 48, 0, 0, 0 },
- { 48, 0, 65536, 0 },
- { 48, 0, 0, 65536 },
- { 48, 0, 65536, 65536 },
- { 48, 0, 1536, 0 },
- { 48, 0, 0, 1536 },
- { 48, 0, 1536, 1536 },
- { 48, 0, 64, 0},
- { 48, 0, 0, 64},
- { 48, 0, 64, 64},
- { 48, 16, 0, 0 },
- { 48, 16, 65536, 0 },
- { 48, 16, 0, 65536 },
- { 48, 16, 65536, 65536 },
- { 48, 16, 1536, 0 },
- { 48, 16, 0, 1536 },
- { 48, 16, 1536, 1536 },
- { 48, 16, 64, 0},
- { 48, 16, 0, 64},
- { 48, 16, 64, 64},
-
- { 64, 0, 0, 0 },
- { 64, 0, 65536, 0 },
- { 64, 0, 0, 65536 },
- { 64, 0, 65536, 65536 },
- { 64, 0, 1536, 0 },
- { 64, 0, 0, 1536 },
- { 64, 0, 1536, 1536 },
- { 64, 0, 64, 0},
- { 64, 0, 0, 64},
- { 64, 0, 64, 64},
- { 64, 16, 0, 0 },
- { 64, 16, 65536, 0 },
- { 64, 16, 0, 65536 },
- { 64, 16, 65536, 65536 },
- { 64, 16, 1536, 0 },
- { 64, 16, 0, 1536 },
- { 64, 16, 1536, 1536 },
- { 64, 16, 64, 0},
- { 64, 16, 0, 64},
- { 64, 16, 64, 64},
-
- { 0, 0, 0, 0 }
-};
-
-static volatile int alarm_rung;
-static void alarm_handler(int num) {
- (void)num;
- alarm_rung = 1;
-}
-
-typedef int (*fn)(AES_SIV_CTX *, unsigned char *, size_t *,
- unsigned char const*, size_t,
- unsigned char const*, size_t,
- unsigned char const*, size_t,
- unsigned char const*, size_t);
-static void
-call(fn fn, AES_SIV_CTX *ctx,
- size_t key_len,
- size_t nonce_len, size_t in_len,
- size_t ad_len) {
-
- size_t out_len = sizeof out;
- size_t count;
- struct timespec start, end;
- double rate;
-
- printf("%3u bit key, %2u byte nonce, %5u byte input, %5u byte associated data: ",
- (unsigned)(key_len * 8), (unsigned)nonce_len,
- (unsigned)in_len, (unsigned)ad_len);
- fflush(stdout);
-
- alarm_rung = 0;
- alarm(3);
-
- if(clock_gettime(CLOCK_MONOTONIC, &start)) {
- perror("clock_gettime");
- exit(1);
- }
- for(count = 0; !alarm_rung; count++) {
- fn(ctx, out, &out_len, key, key_len,
- nonce_len > 0 ? nonce : NULL, nonce_len,
- in, in_len, ad, ad_len);
- }
- if(clock_gettime(CLOCK_MONOTONIC, &end)) {
- perror("clock_gettime");
- exit(1);
- }
-
- rate = (double)count /
- ((double)(end.tv_sec) - (double)(start.tv_sec) +
- ((double)end.tv_nsec - (double)start.tv_nsec)/1000000000.);
- printf("%12.2f calls/second (%11.2f ns/call, %8.2f MiB/s)\n",
- rate,
- 1000000000./rate,
- scalbn(rate * (double)(ad_len + in_len),
- -20));
-}
-
-int main(void) {
- size_t i;
- struct sigaction act;
- AES_SIV_CTX *ctx = AES_SIV_CTX_new();
-
- memset(&act, 0, sizeof act);
- act.sa_handler = alarm_handler;
- if(sigaction(SIGALRM, &act, NULL)) {
- perror("sigaction");
- exit(1);
- }
-
- for(i=0; call_list[i].key_len != 0; i++) {
- printf("Encrypt, ");
- call(AES_SIV_Encrypt, ctx,
- call_list[i].key_len, call_list[i].nonce_len,
- call_list[i].in_len, call_list[i].ad_len);
-
-
- printf("Decrypt, ");
- memcpy(in, out, call_list[i].in_len + 16);
- call(AES_SIV_Decrypt, ctx,
- call_list[i].key_len, call_list[i].nonce_len,
- call_list[i].in_len + 16, call_list[i].ad_len);
-
- printf("Forgery, ");
- memset(in, 0, sizeof in);
- call(AES_SIV_Decrypt, ctx,
- call_list[i].key_len, call_list[i].nonce_len,
- call_list[i].in_len + 16, call_list[i].ad_len);
-
- }
-
- AES_SIV_CTX_free(ctx);
- return 0;
-}
=====================================
libaes_siv/config.h.in deleted
=====================================
@@ -1,19 +0,0 @@
-#ifndef AES_SIV_CONFIG_H_
-#define AES_SIV_CONFIG_H_
-
-/* Enable ct_poison() and ct_unpoison() hooks for testing with
- ctgrind. */
-#cmakedefine ENABLE_CTGRIND 1
-
-/* Enable this to get test coverage for the portable versions of
- putword() and getword() when you don't happen to have a PDP-11
- in your test farm.
-*/
-#cmakedefine ENABLE_DEBUG_WEIRD_ENDIAN 1
-
-/* Enable this to get test coverage for the while loop in do_encrypt()
- without having to have a multi-gigabyte test case that'll take
- forever for Valgrind to crunch through
-*/
-#cmakedefine ENABLE_DEBUG_TINY_CHUNK_SIZE 1
-#endif
=====================================
libaes_siv/demo.c deleted
=====================================
@@ -1,263 +0,0 @@
-/* Copyright Akamai Technologies, Inc.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/** @file
- * Demo program for libaes-siv
- */
-
-#define _POSIX_C_SOURCE 200112L
-#define _ISOC99_SOURCE 1
-
-#include "aes_siv.h"
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/**
- * Load a file into memory.
- * @param[in] filename pathname of the file to load.
- * @param[out] the buf pointer will be set to a new malloc buffer which contains the file data.
- * @param[out] the len pointer will be set to the size of buf in bytes, which is the same as the file size in bytes.
- * @return 0 upon success, the file could be read and the buf,len output parameters have been set.
- * @return -1 on error; errno will be set.
- */
-static int load_file(const char *filename, unsigned char **buf, size_t *len)
-{
- FILE *f = NULL;
- unsigned char *buf_ = NULL;
- size_t len_;
- long ftell_len;
- int saved_errno;
-
- /* Get file size */
- f = fopen(filename, "rb");
- if (f == NULL) {
- goto fail;
- }
-
- if (fseek(f, 0, SEEK_END) < 0) {
- goto fail;
- }
-
- ftell_len = ftell(f);
- if(ftell_len < 0) {
- goto fail;
- }
- len_ = (size_t)ftell_len;
-
- if(fseek(f, 0, SEEK_SET) < 0) {
- goto fail;
- }
-
- /* allocate memory and read */
- buf_ = (unsigned char*) malloc(len_);
- if (buf_ == NULL) {
- goto fail;
- }
- if (fread(buf_, 1, len_, f) != len_) {
- assert(errno);
- goto fail;
- }
-
- fclose(f);
- f = NULL;
- *buf = buf_;
- *len = len_;
- return 0;
-
- fail:
- saved_errno = errno;
- if(f != NULL) {
- fclose(f);
- }
- free(buf_);
- errno = saved_errno;
- return -1;
-}
-
-void help(void)
-{
- fprintf(stderr, "Usage: aes_siv_test [-d] <key file> <ad file> [nonce file]\n");
- fprintf(stderr, "This program encrypts or decrypts STDIN to STDOUT using the AES-SIV algorithm.\n");
- fprintf(stderr, "-d Decrypt STDIN, by default STDIN is encrypted\n");
- fprintf(stderr, "<key file> Filename which is read for key data, must have a size of 32, 48, 64 bytes.\n");
- fprintf(stderr, "<ad file> Filename which is used for associate data. Can have any size.\n");
- fprintf(stderr, "[nonce file] Optional filename which is used for nonce data. Can have any size.\n");
-}
-
-int main(int argc, char const* argv[])
-{
- int arg = 1;
- int decrypt_mode = 0;
- const char *key_file = NULL;
- const char *nonce_file = NULL;
- const char *ad_file = NULL;
- unsigned char *key = NULL;
- size_t key_len = 0;
- unsigned char *nonce = NULL;
- size_t nonce_len = 0;
- unsigned char *ad = NULL;
- size_t ad_len = 0;
- unsigned char *out = NULL;
- size_t out_len = 0;
- size_t plaintext_allocated = 1024;
- unsigned char *plaintext = malloc(plaintext_allocated);
- size_t plaintext_len = 0;
- AES_SIV_CTX *ctx = NULL;
-
- if(plaintext == NULL) {
- perror("malloc");
- goto fail;
- }
-
- /* Parse command line */
- arg = 1;
- if (arg < argc && strcmp(argv[arg], "-d") == 0)
- {
- decrypt_mode = 1;
- ++arg;
- }
-
- if(arg >= argc)
- {
- fprintf(stderr, "Missing key filename\n\n");
- help();
- goto fail;
- }
- key_file = argv[arg++];
-
- if(arg >= argc)
- {
- fprintf(stderr, "Missing associate data filename\n\n");
- help();
- goto fail;
- }
- ad_file = argv[arg++];
-
- if(arg < argc)
- {
- nonce_file = argv[arg++];
- }
-
- if(arg < argc)
- {
- fprintf(stderr, "Unknown command line argument: %s\n\n", argv[arg]);
- help();
- goto fail;
- }
-
- /* Load files */
- if(load_file(key_file, &key, &key_len) < 0)
- {
- fprintf(stderr, "Could not load key file %s : %s\n", key_file, strerror(errno));
- goto fail;
- }
-
- assert(key != NULL);
- if(! (key_len == 32 ||
- key_len == 48 ||
- key_len == 64))
- {
- fprintf(stderr, "Invalid key length %zu bytes, must be one of 32, 48, or 64\n", key_len);
- goto fail;
- }
-
- if(load_file(ad_file, &ad, &ad_len) < 0)
- {
- fprintf(stderr, "Could not load associated data file %s : %s\n", ad_file, strerror(errno));
- goto fail;
- }
- assert(ad);
- assert(ad_len > 0);
- if(load_file(nonce_file, &nonce, &nonce_len) < 0)
- {
- fprintf(stderr, "could not load nonce file %s : %s\n", nonce_file, strerror(errno));
- goto fail;
- }
-
- /* Read all of STDIN */
- while(!feof(stdin))
- {
- unsigned char buf[1024];
- unsigned char *plaintext_new;
- size_t r = fread(buf, 1, sizeof(buf), stdin);
- if(r > 0)
- {
- if(plaintext_len + r > plaintext_allocated)
- {
- plaintext_allocated *= 2;
- plaintext_new = realloc(plaintext, plaintext_allocated);
- if(plaintext_new == NULL)
- {
- perror("realloc");
- goto fail;
- }
- plaintext = plaintext_new;
- }
- assert(plaintext_len + r <= plaintext_allocated);
- memcpy(plaintext + plaintext_len, buf, r);
- plaintext_len += r;
- } else if(ferror(stdin)) {
- perror("fread");
- goto fail;
- }
- }
-
- /* allocate output buffer */
- out_len = plaintext_len + 16;
- out = (unsigned char*) malloc(out_len);
- if (out == NULL)
- {
- perror("malloc");
- goto fail;
- }
-
- /* do AES-SIV */
- ctx = AES_SIV_CTX_new();
- if (ctx == NULL)
- {
- perror("AES_SIV_CTX_new");
- goto fail;
- }
- if (decrypt_mode)
- {
- if (AES_SIV_Decrypt(ctx, out, &out_len, key, key_len, nonce, nonce_len, plaintext, plaintext_len, ad, ad_len) != 1)
- {
- fprintf(stderr, "Could not decrypt AES-SIV\n");
- goto fail;
- }
- }
- else
- {
- if (AES_SIV_Encrypt(ctx, out, &out_len, key, key_len, nonce, nonce_len, plaintext, plaintext_len, ad, ad_len) != 1)
- {
- fprintf(stderr, "Could not encrypt AES-SIV\n");
- goto fail;
- }
- }
- AES_SIV_CTX_free(ctx);
-
- /* write to stdout */
- if(fwrite(out, 1, out_len, stdout) < out_len) {
- perror("fwrite");
- goto fail;
- }
-
- free(plaintext);
- free(key);
- free(ad);
- free(nonce);
- free(out);
- return EXIT_SUCCESS;
-
- fail:
- free(plaintext);
- free(key);
- free(ad);
- free(nonce);
- free(out);
- return EXIT_FAILURE;
-}
=====================================
libaes_siv/tests.c deleted
=====================================
@@ -1,586 +0,0 @@
-/* Copyright Akamai Technologies, Inc.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-#define _POSIX_C_SOURCE 200112L
-#define _ISOC99_SOURCE 1
-
-#include "config.h"
-#include "aes_siv.h"
-
-#undef NDEBUG
-#include <assert.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/opensslv.h>
-
-static void debug(const char *label, const unsigned char *hex, size_t len) {
- size_t i;
- printf("%16s: ", label);
- for (i = 0; i < len; i++) {
- if (i > 0 && i % 16 == 0) {
- printf("\n ");
- }
- printf("%.2x", (unsigned int)hex[i]);
- if (i > 0 && i % 4 == 3) {
- printf(" ");
- }
- }
- printf("\n");
-}
-
-static int fail_allocation_counter = -1;
-
-static void* mock_malloc(size_t num) {
- if(fail_allocation_counter < 0) {
- return malloc(num);
- }
- if(fail_allocation_counter-- == 0) {
- return NULL;
- }
- return malloc(num);
-}
-
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
-static void* mock_malloc_ex(size_t num, const char *file, int line) {
- (void)file;
- (void)line;
- return mock_malloc(num);
-}
-
-static void *mock_realloc_ex(void *mem, size_t num, const char *file, int line) {
- (void)file;
- (void)line;
- return realloc(mem, num);
-}
-
-static void mock_free_ex(void *mem, const char* file, int line) {
- (void)file;
- (void)line;
- free(mem);
-}
-#endif
-
-/* This needs to be the first test case because CRYPTO_set_mem_functions()
- will fail once any allocations have happened.
-*/
-static void test_malloc_failure(void) {
- int ret, i=0;
- AES_SIV_CTX *ctx;
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- ret = CRYPTO_set_mem_functions(mock_malloc, realloc, free);
-#else
- ret = CRYPTO_set_mem_functions(mock_malloc_ex, mock_realloc_ex, mock_free_ex);
-#endif
- assert(ret == 1);
-
- printf("Test allocation failure cases:\n" );
-
- do {
- fail_allocation_counter = i++;
- } while((ctx = AES_SIV_CTX_new()) == NULL);
- assert(i > 1);
- printf("AES_SIV_CTX_new() succeeds after %d successful allocations.\n", i-1);
- AES_SIV_CTX_free(ctx);
- fail_allocation_counter = -1;
-}
-
-static void test_cleanup_before_free(void) {
- printf("Test cleanup before free: ");
- AES_SIV_CTX *ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
- AES_SIV_CTX_cleanup(ctx);
- AES_SIV_CTX_free(ctx);
- printf("OK\n");
-}
-
-static void test_vector_1(void) {
- const unsigned char key[] = {
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
- };
-
- const unsigned char ad[] = {
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
- };
-
- const unsigned char plaintext[] = {
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
- 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee};
-
- const unsigned char ciphertext[] = {
- 0x85, 0x63, 0x2d, 0x07, 0xc6, 0xe8, 0xf3, 0x7f,
- 0x95, 0x0a, 0xcd, 0x32, 0x0a, 0x2e, 0xcc, 0x93,
- 0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04,
- 0xda, 0xef, 0x7f, 0x6a, 0xfe, 0x5c
- };
-
- unsigned char ciphertext_out[256];
- unsigned char plaintext_out[256];
-
- size_t plaintext_len = sizeof plaintext_out;
- size_t ciphertext_len = sizeof ciphertext_out;
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("Test vector 1:\n");
- debug("key", key, sizeof key);
- debug("AD", ad, sizeof ad);
- debug("plaintext", plaintext, sizeof plaintext);
- debug("exp. ciphertext", ciphertext, sizeof ciphertext);
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- printf("Encryption:\n");
- ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
- sizeof key, NULL, 0, plaintext, sizeof plaintext,
- ad, sizeof ad);
- assert(ret == 1);
- assert(ciphertext_len == sizeof ciphertext);
- assert(!memcmp(ciphertext, ciphertext_out, ciphertext_len));
-
- printf("Decryption:\n");
- ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
- sizeof key, NULL, 0, ciphertext_out,
- ciphertext_len, ad, sizeof ad);
- assert(ret == 1);
- assert(plaintext_len == sizeof plaintext);
- assert(!memcmp(plaintext, plaintext_out, plaintext_len));
- AES_SIV_CTX_free(ctx);
-}
-
-static void test_vector_2(void) {
- const unsigned char key[] = {
- 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
- 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
- };
-
- const unsigned char ad1[] = {
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
- 0xde, 0xad, 0xda, 0xda, 0xde, 0xad, 0xda, 0xda,
- 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
- 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00
- };
-
- const unsigned char ad2[] = {
- 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
- 0x90, 0xa0
- };
-
- const unsigned char nonce[] = {
- 0x09, 0xf9, 0x11, 0x02, 0x9d, 0x74, 0xe3, 0x5b,
- 0xd8, 0x41, 0x56, 0xc5, 0x63, 0x56, 0x88, 0xc0
- };
-
- const unsigned char plaintext[] = {
- 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
- 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x6c, 0x61,
- 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74,
- 0x6f, 0x20, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
- 0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20,
- 0x53, 0x49, 0x56, 0x2d, 0x41, 0x45, 0x53
- };
-
- const unsigned char ciphertext[] = {
- 0x7b, 0xdb, 0x6e, 0x3b, 0x43, 0x26, 0x67, 0xeb,
- 0x06, 0xf4, 0xd1, 0x4b, 0xff, 0x2f, 0xbd, 0x0f,
- 0xcb, 0x90, 0x0f, 0x2f, 0xdd, 0xbe, 0x40, 0x43,
- 0x26, 0x60, 0x19, 0x65, 0xc8, 0x89, 0xbf, 0x17,
- 0xdb, 0xa7, 0x7c, 0xeb, 0x09, 0x4f, 0xa6, 0x63,
- 0xb7, 0xa3, 0xf7, 0x48, 0xba, 0x8a, 0xf8, 0x29,
- 0xea, 0x64, 0xad, 0x54, 0x4a, 0x27, 0x2e, 0x9c,
- 0x48, 0x5b, 0x62, 0xa3, 0xfd, 0x5c, 0x0d
- };
-
- unsigned char ciphertext_out[256];
- unsigned char plaintext_out[256];
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("Test vector 2:\n");
- debug("key", key, sizeof key);
- debug("AD1", ad1, sizeof ad1);
- debug("AD2", ad2, sizeof ad2);
- debug("nonce", nonce, sizeof nonce);
- debug("plaintext", plaintext, sizeof plaintext);
- debug("exp. ciphertext", ciphertext, sizeof ciphertext);
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- printf("Encryption:\n");
- ret = AES_SIV_Init(ctx, key, sizeof key);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx, ad1, sizeof ad1);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx, ad2, sizeof ad2);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx, nonce, sizeof nonce);
- assert(ret == 1);
- ret = AES_SIV_EncryptFinal(ctx, ciphertext_out, ciphertext_out + 16,
- plaintext, sizeof plaintext);
- assert(ret == 1);
- debug("IV || C", ciphertext_out, sizeof plaintext + 16);
- assert(!memcmp(ciphertext_out, ciphertext, sizeof ciphertext));
-
- printf("Decryption:\n");
- ret = AES_SIV_Init(ctx, key, sizeof key);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx, ad1, sizeof ad1);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx, ad2, sizeof ad2);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx, nonce, sizeof nonce);
- assert(ret == 1);
- ret = AES_SIV_DecryptFinal(ctx, plaintext_out, ciphertext_out,
- ciphertext_out + 16, sizeof plaintext);
- assert(ret == 1);
- debug("plaintext", plaintext_out, sizeof plaintext);
- assert(!memcmp(plaintext_out, plaintext, sizeof plaintext));
- AES_SIV_CTX_free(ctx);
-}
-
-static void test_384bit(void) {
- const unsigned char key[] = {
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0
- };
-
- const unsigned char ad[] = {
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
- };
-
- const unsigned char plaintext[] = {
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
- 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
- };
-
- const unsigned char ciphertext[] = {
- 0x89, 0xe8, 0x69, 0xb9, 0x32, 0x56, 0x78, 0x51,
- 0x54, 0xf0, 0x96, 0x39, 0x62, 0xfe, 0x07, 0x40,
- 0xef, 0xf3, 0x56, 0xe4, 0x2d, 0xec, 0x1f, 0x4f,
- 0xeb, 0xde, 0xd3, 0x66, 0x42, 0xf2
- };
-
- unsigned char ciphertext_out[256];
- unsigned char plaintext_out[256];
-
- size_t plaintext_len = sizeof plaintext_out;
- size_t ciphertext_len = sizeof ciphertext_out;
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("384-bit key test:\n");
- debug("key", key, sizeof key);
- debug("AD", ad, sizeof ad);
- debug("plaintext", plaintext, sizeof plaintext);
- debug("exp. ciphertext", ciphertext, sizeof ciphertext);
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- printf("Encryption:\n");
- ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
- sizeof key, NULL, 0, plaintext, sizeof plaintext,
- ad, sizeof ad);
- assert(ret == 1);
- assert(ciphertext_len == sizeof ciphertext);
- assert(!memcmp(ciphertext, ciphertext_out, ciphertext_len));
-
- printf("Decryption:\n");
- ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
- sizeof key, NULL, 0, ciphertext_out,
- ciphertext_len, ad, sizeof ad);
- assert(ret == 1);
- assert(plaintext_len == sizeof plaintext);
- assert(!memcmp(plaintext, plaintext_out, plaintext_len));
- AES_SIV_CTX_free(ctx);
-}
-
-static void test_512bit(void) {
- const unsigned char key[] = {
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0
- };
-
- const unsigned char ad[] = {
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
- };
-
- const unsigned char plaintext[] = {
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
- 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
- };
-
- const unsigned char ciphertext[] = {
- 0x72, 0x4d, 0xfb, 0x2e, 0xaf, 0x94, 0xdb, 0xb1,
- 0x9b, 0x0b, 0xa3, 0xa2, 0x99, 0xa0, 0x80, 0x1e,
- 0xf3, 0xb0, 0x5a, 0x55, 0x49, 0x8e, 0xc2, 0x55,
- 0x26, 0x90, 0xb8, 0x98, 0x10, 0xe4
- };
-
- unsigned char ciphertext_out[256];
- unsigned char plaintext_out[256];
-
- size_t plaintext_len = sizeof plaintext_out;
- size_t ciphertext_len = sizeof ciphertext_out;
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("512-bit key test:\n");
- debug("key", key, sizeof key);
- debug("AD", ad, sizeof ad);
- debug("plaintext", plaintext, sizeof plaintext);
- debug("exp. ciphertext", ciphertext, sizeof ciphertext);
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- printf("Encryption:\n");
- ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
- sizeof key, NULL, 0, plaintext, sizeof plaintext,
- ad, sizeof ad);
- assert(ret == 1);
- assert(ciphertext_len == sizeof ciphertext);
- assert(!memcmp(ciphertext, ciphertext_out, ciphertext_len));
-
- printf("Decryption:\n");
- ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
- sizeof key, NULL, 0, ciphertext_out,
- ciphertext_len, ad, sizeof ad);
- assert(ret == 1);
- assert(plaintext_len == sizeof plaintext);
- assert(!memcmp(plaintext, plaintext_out, plaintext_len));
- AES_SIV_CTX_free(ctx);
-}
-
-static void test_highlevel_with_nonce(void) {
- const unsigned char key[] = {
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
- };
-
- const unsigned char ad[] = {
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
- };
-
- const unsigned char nonce[] = {
- 0x09, 0xf9, 0x11, 0x02, 0x9d, 0x74, 0xe3, 0x5b,
- 0xd8, 0x41, 0x56, 0xc5, 0x63, 0x56, 0x88, 0xc0
- };
-
- const unsigned char plaintext[] = {
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
- 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
- };
-
- unsigned char ciphertext_out[256];
- unsigned char plaintext_out[256];
-
- size_t plaintext_len = sizeof plaintext_out;
- size_t ciphertext_len = sizeof ciphertext_out;
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("Test high-level interface with non-NULL nonce:\n");
- debug("key", key, sizeof key);
- debug("AD", ad, sizeof ad);
- debug("nonce", nonce, sizeof nonce);
- debug("plaintext", plaintext, sizeof plaintext);
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- printf("Encryption:\n");
- ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
- sizeof key, nonce, sizeof nonce, plaintext,
- sizeof plaintext, ad, sizeof ad);
- assert(ret == 1);
-
- printf("Decryption:\n");
- ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
- sizeof key, nonce, sizeof nonce, ciphertext_out,
- ciphertext_len, ad, sizeof ad);
- assert(ret == 1);
- assert(plaintext_len == sizeof plaintext);
- assert(!memcmp(plaintext, plaintext_out, plaintext_len));
- AES_SIV_CTX_free(ctx);
-}
-
-static void test_copy(void) {
- const unsigned char key[] = {
- 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
- };
-
- const unsigned char ad[] = {
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
- };
-
- const unsigned char plaintext1[] = {
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
- 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee
- };
-
- const unsigned char plaintext2[] = {
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
- 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xef
- };
-
- const unsigned char ciphertext[] = {
- 0x85, 0x63, 0x2d, 0x07, 0xc6, 0xe8, 0xf3, 0x7f,
- 0x95, 0x0a, 0xcd, 0x32, 0x0a, 0x2e, 0xcc, 0x93,
- 0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04,
- 0xda, 0xef, 0x7f, 0x6a, 0xfe, 0x5c
- };
-
- unsigned char ciphertext1_out[256], ciphertext2_out[256];
-
- AES_SIV_CTX *ctx1, *ctx2, *ctx3;
- int ret;
-
- ctx1 = AES_SIV_CTX_new();
- assert(ctx1 != NULL);
- ctx2 = AES_SIV_CTX_new();
- assert(ctx2 != NULL);
- ctx3 = AES_SIV_CTX_new();
- assert(ctx3 != NULL);
-
- ret = AES_SIV_Init(ctx1, key, sizeof key);
- assert(ret == 1);
- ret = AES_SIV_CTX_copy(ctx2, ctx1);
- assert(ret == 1);
-
- ret = AES_SIV_AssociateData(ctx1, ad, sizeof ad);
- assert(ret == 1);
- ret = AES_SIV_AssociateData(ctx2, ad, sizeof ad);
- assert(ret == 1);
-
- ret = AES_SIV_CTX_copy(ctx3, ctx1);
- assert(ret == 1);
-
- ret = AES_SIV_EncryptFinal(ctx1, ciphertext1_out, ciphertext1_out + 16,
- plaintext1, sizeof plaintext1);
- assert(ret == 1);
- assert(!memcmp(ciphertext, ciphertext1_out, sizeof ciphertext));
-
- ret = AES_SIV_EncryptFinal(ctx2, ciphertext2_out, ciphertext2_out + 16,
- plaintext1, sizeof plaintext1);
- assert(ret == 1);
- assert(!memcmp(ciphertext, ciphertext2_out, sizeof ciphertext));
-
- ret = AES_SIV_EncryptFinal(ctx3, ciphertext2_out, ciphertext2_out + 16,
- plaintext2, sizeof plaintext2);
- assert(ret == 1);
- assert(memcmp(ciphertext, ciphertext2_out, sizeof ciphertext));
-
- AES_SIV_CTX_free(ctx1);
- AES_SIV_CTX_free(ctx2);
- AES_SIV_CTX_free(ctx3);
-}
-
-static void test_bad_key(void) {
- static const unsigned char key[40];
- static const unsigned char ad[16];
- static const unsigned char plaintext[16];
-
- unsigned char ciphertext_out[256];
- size_t ciphertext_len = sizeof ciphertext_out;
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("Test bad key size: ");
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- ret = AES_SIV_Encrypt(ctx, ciphertext_out, &ciphertext_len, key,
- sizeof key, NULL, 0, plaintext, sizeof plaintext,
- ad, sizeof ad);
- assert(ret == 0);
-
- ret = AES_SIV_Init(ctx, key, sizeof key);
- assert(ret == 0);
-
- AES_SIV_CTX_free(ctx);
- printf("OK\n");
-}
-
-static void test_decrypt_failure(void) {
- static const unsigned char key[32];
- static const unsigned char ad[16];
- static const unsigned char ciphertext[32];
-
- unsigned char plaintext_out[256];
- size_t plaintext_len = sizeof plaintext_out;
-
- AES_SIV_CTX *ctx;
- int ret;
-
- printf("Test decryption failure:\n");
-
- ctx = AES_SIV_CTX_new();
- assert(ctx != NULL);
-
- ret = AES_SIV_Decrypt(ctx, plaintext_out, &plaintext_len, key,
- sizeof key, NULL, 0, ciphertext,
- sizeof ciphertext, ad, sizeof ad);
- assert(ret == 0);
-
- AES_SIV_CTX_free(ctx);
-}
-
-int main(void) {
- test_malloc_failure();
- test_cleanup_before_free();
- test_vector_1();
- test_vector_2();
- test_384bit();
- test_512bit();
- test_highlevel_with_nonce();
- test_copy();
- test_bad_key();
- test_decrypt_failure();
- return 0;
-}
=====================================
libaes_siv/wscript deleted
=====================================
@@ -1,37 +0,0 @@
-# Copyright the NTPsec project contributors
-#
-# SPDX-License-Identifier: BSD-2-Clause
-
-def build(ctx):
- aes_cflags=['-Wno-shadow',
- # '-Wall', '-Wextra', '-Wstrict-prototypes', # default
- # '-Wconversion', # Overzealous in GCC 4.2
- '-O3',
- '-fomit-frame-pointer',
- '-funroll-loops',
- '-ftree-vectorize',
- '-Wno-inline', # gcc 10 gives inline warnings?
- ]
-
-
- ctx(
- target='aes_siv',
- features='c cstlib',
- includes=[ctx.bldnode.parent.abspath()],
- source='aes_siv.c',
- use='CRYPTO',
- cflags=aes_cflags,
- )
-
- ctx(
- target="runtests",
- features="c cprogram test",
- includes=[ctx.bldnode.parent.abspath()],
- source=[
- "aes_siv_test.c",
- "tests.c",
- ],
- install_path=None,
- use="aes_siv",
- cflags=aes_cflags,
- )
=====================================
libntp/aes_siv_evp.c
=====================================
@@ -0,0 +1,292 @@
+/*
+ * aes_siv_evp.c - AES-SIV wrapper using OpenSSL 3.x EVP
+ * Copyright the NTPsec project contributors
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This provides the same API as libaes_siv but uses OpenSSL 3.x native
+ * EVP_CIPHER AES-SIV support instead of the bundled libaes_siv library.
+ *
+ * OpenSSL 3.x provides AES-SIV via EVP_CIPHER with names:
+ * "AES-128-SIV" for 256-bit key (32 bytes)
+ * "AES-192-SIV" for 384-bit key (48 bytes)
+ * "AES-256-SIV" for 512-bit key (64 bytes)
+ *
+ * Note: The key length for SIV is double the AES variant because SIV
+ * uses two keys internally (one for S2V/CMAC, one for CTR encryption).
+ */
+
+#include "config.h"
+#include "aes_siv_evp.h"
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+/* SIV tag length is always 16 bytes */
+#define SIV_TAG_LEN 16
+
+/*
+ * Context structure for AES-SIV operations.
+ * We cache the EVP_CIPHER_CTX for potential reuse, though the one-shot
+ * functions reset it on each call anyway.
+ */
+struct AES_SIV_CTX_st {
+ EVP_CIPHER_CTX *cipher_ctx;
+};
+
+AES_SIV_CTX *AES_SIV_CTX_new(void) {
+ AES_SIV_CTX *ctx;
+
+ ctx = OPENSSL_zalloc(sizeof(struct AES_SIV_CTX_st));
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ ctx->cipher_ctx = EVP_CIPHER_CTX_new();
+ if (ctx->cipher_ctx == NULL) {
+ OPENSSL_free(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+void AES_SIV_CTX_cleanup(AES_SIV_CTX *ctx) {
+ if (ctx != NULL && ctx->cipher_ctx != NULL) {
+ EVP_CIPHER_CTX_reset(ctx->cipher_ctx);
+ }
+}
+
+void AES_SIV_CTX_free(AES_SIV_CTX *ctx) {
+ if (ctx != NULL) {
+ EVP_CIPHER_CTX_free(ctx->cipher_ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+int AES_SIV_CTX_copy(AES_SIV_CTX *dst, AES_SIV_CTX const *src) {
+ if (dst == NULL || src == NULL) {
+ return 0;
+ }
+ return EVP_CIPHER_CTX_copy(dst->cipher_ctx, src->cipher_ctx);
+}
+
+/*
+ * Get the cipher name for a given key length.
+ * Returns NULL for invalid key lengths.
+ */
+static const char *get_cipher_name(size_t key_len) {
+ switch (key_len) {
+ case 32:
+ return "AES-128-SIV";
+ case 48:
+ return "AES-192-SIV";
+ case 64:
+ return "AES-256-SIV";
+ default:
+ return NULL;
+ }
+}
+
+int AES_SIV_Encrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
+ unsigned char const *key, size_t key_len,
+ unsigned char const *nonce, size_t nonce_len,
+ unsigned char const *plaintext, size_t plaintext_len,
+ unsigned char const *ad, size_t ad_len) {
+ EVP_CIPHER *cipher = NULL;
+ const char *cipher_name;
+ int len;
+ int ret = 0;
+ size_t required_len;
+ unsigned char *tag_out;
+ unsigned char *ct_out;
+
+ if (ctx == NULL || ctx->cipher_ctx == NULL) {
+ return 0;
+ }
+
+ /* Output must have room for tag + ciphertext */
+ required_len = plaintext_len + SIV_TAG_LEN;
+ if (*out_len < required_len) {
+ return 0;
+ }
+
+ cipher_name = get_cipher_name(key_len);
+ if (cipher_name == NULL) {
+ return 0;
+ }
+
+ /* Fetch the cipher */
+ cipher = EVP_CIPHER_fetch(NULL, cipher_name, NULL);
+ if (cipher == NULL) {
+ return 0;
+ }
+
+ /* Reset context for new operation */
+ EVP_CIPHER_CTX_reset(ctx->cipher_ctx);
+
+ /* Initialize encryption */
+ if (EVP_EncryptInit_ex2(ctx->cipher_ctx, cipher, key, NULL, NULL) != 1) {
+ goto cleanup;
+ }
+
+ /*
+ * In OpenSSL's AES-SIV implementation:
+ * - Pass AD components via EVP_EncryptUpdate with NULL output
+ * - The original libaes_siv treats nonce as an additional AD component
+ * (called after the main AD in the S2V computation)
+ * - OpenSSL processes AD components in the order they are provided
+ *
+ * From RFC 5297: S2V takes a sequence of strings (AD1, AD2, ..., ADn, plaintext)
+ * The original code does: S2V(AD, nonce, plaintext)
+ */
+
+ /* Add main associated data */
+ if (ad != NULL && ad_len > 0) {
+ if (EVP_EncryptUpdate(ctx->cipher_ctx, NULL, &len, ad, (int)ad_len) != 1) {
+ goto cleanup;
+ }
+ }
+
+ /* Add nonce as additional associated data */
+ if (nonce != NULL && nonce_len > 0) {
+ if (EVP_EncryptUpdate(ctx->cipher_ctx, NULL, &len, nonce, (int)nonce_len) != 1) {
+ goto cleanup;
+ }
+ }
+
+ /*
+ * SIV output format: tag (16 bytes) || ciphertext
+ * We need to write ciphertext after the tag position
+ */
+ tag_out = out;
+ ct_out = out + SIV_TAG_LEN;
+
+ /* Encrypt the plaintext (use empty buffer if NULL to satisfy OpenSSL) */
+ unsigned char empty = 0;
+ const unsigned char *pt = (plaintext != NULL) ? plaintext : ∅
+ if (EVP_EncryptUpdate(ctx->cipher_ctx, ct_out, &len, pt, (int)plaintext_len) != 1) {
+ goto cleanup;
+ }
+
+ /* Finalize - for SIV this doesn't produce additional output */
+ if (EVP_EncryptFinal_ex(ctx->cipher_ctx, ct_out + len, &len) != 1) {
+ goto cleanup;
+ }
+
+ /* Get the SIV tag */
+ if (EVP_CIPHER_CTX_ctrl(ctx->cipher_ctx, EVP_CTRL_AEAD_GET_TAG, SIV_TAG_LEN, tag_out) != 1) {
+ goto cleanup;
+ }
+
+ *out_len = required_len;
+ ret = 1;
+
+cleanup:
+ EVP_CIPHER_free(cipher);
+ if (ret != 1) {
+ /* Clear output on failure */
+ OPENSSL_cleanse(out, required_len);
+ }
+ return ret;
+}
+
+int AES_SIV_Decrypt(AES_SIV_CTX *ctx, unsigned char *out, size_t *out_len,
+ unsigned char const *key, size_t key_len,
+ unsigned char const *nonce, size_t nonce_len,
+ unsigned char const *ciphertext, size_t ciphertext_len,
+ unsigned char const *ad, size_t ad_len) {
+ EVP_CIPHER *cipher = NULL;
+ const char *cipher_name;
+ int len;
+ int ret = 0;
+ size_t plaintext_len;
+ const unsigned char *tag_in;
+ const unsigned char *ct_in;
+
+ if (ctx == NULL || ctx->cipher_ctx == NULL) {
+ return 0;
+ }
+
+ /* Ciphertext must be at least the tag length */
+ if (ciphertext_len < SIV_TAG_LEN) {
+ return 0;
+ }
+
+ plaintext_len = ciphertext_len - SIV_TAG_LEN;
+
+ /* Output must have room for plaintext */
+ if (*out_len < plaintext_len) {
+ return 0;
+ }
+
+ cipher_name = get_cipher_name(key_len);
+ if (cipher_name == NULL) {
+ return 0;
+ }
+
+ /* Fetch the cipher */
+ cipher = EVP_CIPHER_fetch(NULL, cipher_name, NULL);
+ if (cipher == NULL) {
+ return 0;
+ }
+
+ /* Reset context for new operation */
+ EVP_CIPHER_CTX_reset(ctx->cipher_ctx);
+
+ /* Initialize decryption */
+ if (EVP_DecryptInit_ex2(ctx->cipher_ctx, cipher, key, NULL, NULL) != 1) {
+ goto cleanup;
+ }
+
+ /*
+ * SIV input format: tag (16 bytes) || ciphertext
+ */
+ tag_in = ciphertext;
+ ct_in = ciphertext + SIV_TAG_LEN;
+
+ /* Set the expected tag for verification */
+ if (EVP_CIPHER_CTX_ctrl(ctx->cipher_ctx, EVP_CTRL_AEAD_SET_TAG,
+ SIV_TAG_LEN, (void *)tag_in) != 1) {
+ goto cleanup;
+ }
+
+ /* Add main associated data */
+ if (ad != NULL && ad_len > 0) {
+ if (EVP_DecryptUpdate(ctx->cipher_ctx, NULL, &len, ad, (int)ad_len) != 1) {
+ goto cleanup;
+ }
+ }
+
+ /* Add nonce as additional associated data */
+ if (nonce != NULL && nonce_len > 0) {
+ if (EVP_DecryptUpdate(ctx->cipher_ctx, NULL, &len, nonce, (int)nonce_len) != 1) {
+ goto cleanup;
+ }
+ }
+
+ /* Decrypt the ciphertext (use empty buffers if NULL to satisfy OpenSSL) */
+ unsigned char empty = 0;
+ unsigned char *out_ptr = (out != NULL) ? out : ∅
+ const unsigned char *ct_ptr = (plaintext_len > 0) ? ct_in : ∅
+ if (EVP_DecryptUpdate(ctx->cipher_ctx, out_ptr, &len, ct_ptr, (int)plaintext_len) != 1) {
+ goto cleanup;
+ }
+
+ /* Finalize and verify authentication tag */
+ if (EVP_DecryptFinal_ex(ctx->cipher_ctx, out_ptr + len, &len) != 1) {
+ /* Authentication failed - clear output */
+ if (out != NULL && plaintext_len > 0) {
+ OPENSSL_cleanse(out, plaintext_len);
+ }
+ goto cleanup;
+ }
+
+ *out_len = plaintext_len;
+ ret = 1;
+
+cleanup:
+ EVP_CIPHER_free(cipher);
+ return ret;
+}
=====================================
libntp/wscript
=====================================
@@ -11,6 +11,7 @@ from waflib.Logs import pprint
def build(ctx):
libntp_source = [
+ "aes_siv_evp.c",
"authkeys.c",
"authreadkeys.c",
"clocktime.c",
=====================================
ntpd/nts_cookie.c
=====================================
@@ -10,9 +10,9 @@
* It uses AEAD_AES_SIV_CMAC_256/384/512 from RFC 5297
* The selection is done by the key length.
*
- * We use the implementation in libaes_siv by Daniel Franke (Akamai)
- * There is a similar implementation in OpenSSL (or soon will be)
- * It has a slightly different API. See libaes_siv/README.md
+ * We use the AES-SIV implementation in OpenSSL 3.0+ via an EVP wrapper
+ * that provides a libaes_siv-compatible API.
+ * See aes_siv_evp.c for the wrapper implementation.
*
*/
@@ -28,7 +28,7 @@
#include <pthread.h>
#include <unistd.h>
-#include <aes_siv.h>
+#include "aes_siv_evp.h"
#include "ntpd.h"
#include "ntp_stdlib.h"
=====================================
ntpd/nts_extens.c
=====================================
@@ -18,7 +18,7 @@
#include <stdint.h>
#include <string.h>
-#include <aes_siv.h>
+#include "aes_siv_evp.h"
#include "ntp_stdlib.h"
#include "ntp.h"
=====================================
ntpd/wscript
=====================================
@@ -67,10 +67,10 @@ def build(ctx):
ctx(
features="c",
- includes=[ctx.bldnode.parent.abspath(), "../include", "../libaes_siv"],
+ includes=[ctx.bldnode.parent.abspath(), "../include"],
source=libntpd_source,
target="libntpd_obj",
- use="CRYPTO aes_siv",
+ use="CRYPTO",
)
ctx(
=====================================
tests/ntpd/nts_cookie.c
=====================================
@@ -9,7 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "aes_siv.h"
+#include "aes_siv_evp.h"
extern AES_SIV_CTX* cookie_ctx;
extern uint8_t K[NTS_MAX_KEYLEN], K2[NTS_MAX_KEYLEN];
=====================================
tests/ntpd/nts_extens.c
=====================================
@@ -8,7 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "aes_siv.h"
+#include "aes_siv_evp.h"
/* base_pkt is the size of a bare NTP packet, used for constructing
* dummy packets to feed into the tests */
=====================================
wafhelpers/openssl.py
=====================================
@@ -26,11 +26,13 @@ def check_libssl_tls13(ctx):
)
-SNIP_OPENSSL_BAD_VERSION_CHECK = """
+SNIP_OPENSSL_VERSION_CHECK = """
#include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER == 0x1010101fL
-#error OpenSSL version must not be 1.1.1a
+/* OpenSSL 3.0+ required for native AES-SIV support used by NTS.
+ * LibreSSL does not provide AES-SIV and is not supported. */
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#error OpenSSL must be version 3.0.0 or newer
#endif
int main(void) {
@@ -39,12 +41,12 @@ int main(void) {
"""
-def check_openssl_bad_version(ctx):
- """Report if OpenSSL has a good version to ./waf configure."""
+def check_openssl_version(ctx):
+ """Require OpenSSL >= 3.0 for ./waf configure."""
ctx.check_cc(
- fragment=SNIP_OPENSSL_BAD_VERSION_CHECK,
+ fragment=SNIP_OPENSSL_VERSION_CHECK,
use="SSL CRYPTO",
- msg="Checking for OpenSSL != 1.1.1a",
+ msg="Checking for OpenSSL >= 3.0",
)
=====================================
wscript
=====================================
@@ -853,10 +853,10 @@ int main(int argc, char **argv) {
if not ctx.env.DISABLE_NTS:
from wafhelpers.openssl import check_libssl_tls13
- from wafhelpers.openssl import check_openssl_bad_version
+ from wafhelpers.openssl import check_openssl_version
from wafhelpers.openssl import dump_openssl_version
check_libssl_tls13(ctx)
- check_openssl_bad_version(ctx)
+ check_openssl_version(ctx)
dump_openssl_version(ctx)
# before write_config()
@@ -1050,8 +1050,6 @@ def build(ctx):
# required by the generic and Trimble refclocks
ctx.recurse("libparse")
ctx.recurse("libntp")
- if not ctx.env.DISABLE_NTS:
- ctx.recurse("libaes_siv")
ctx.recurse("ntpd")
ctx.recurse("ntpfrob")
ctx.recurse("ntptime")
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/7b9b9c427bde87e7cf76cae3e616586859ca42a8...b6c8aa9c05eeecccdb116a849e11a1fcaca3e50b
--
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/7b9b9c427bde87e7cf76cae3e616586859ca42a8...b6c8aa9c05eeecccdb116a849e11a1fcaca3e50b
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20260622/4536c911/attachment-0001.htm>
More information about the vc
mailing list