diff --git a/Lib/hmac.py b/Lib/hmac.py index 8b4eb2fe741e60..47bb25913c7891 100644 --- a/Lib/hmac.py +++ b/Lib/hmac.py @@ -3,7 +3,6 @@ Implements the HMAC algorithm as described by RFC 2104. """ -import warnings as _warnings try: import _hashlib as _hashopenssl except ImportError: @@ -14,6 +13,14 @@ compare_digest = _hashopenssl.compare_digest _functype = type(_hashopenssl.openssl_sha256) # builtin type +try: + import _hmac +except ImportError: + _hmac = None + _functype = None +else: + _functype = type(_hmac.compute_md5) # builtin type + import hashlib as _hashlib trans_5C = bytes((x ^ 0x5C) for x in range(256)) @@ -84,11 +91,15 @@ def _init_old(self, key, msg, digestmod): if hasattr(self._inner, 'block_size'): blocksize = self._inner.block_size if blocksize < 16: + import warnings as _warnings + _warnings.warn('block_size of %d seems too small; using our ' 'default of %d.' % (blocksize, self.blocksize), RuntimeWarning, 2) blocksize = self.blocksize else: + import warnings as _warnings + _warnings.warn('No block_size attribute on given digest object; ' 'Assuming %d.' % (self.blocksize), RuntimeWarning, 2) @@ -193,6 +204,12 @@ def digest(key, msg, digest): A hashlib constructor returning a new hash object. *OR* A module supporting PEP 247. """ + if _hmac is not None and isinstance(digest, (str, _functype)): + try: + return _hmac.compute_digest(key, msg, digest) + except (OverflowError, _hashopenssl.UnsupportedDigestmodError): + pass + if _hashopenssl is not None and isinstance(digest, (str, _functype)): try: return _hashopenssl.hmac_digest(key, msg, digest) diff --git a/Makefile.pre.in b/Makefile.pre.in index 8d94ba361fd934..6740ca577dff49 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -227,8 +227,12 @@ ENSUREPIP= @ENSUREPIP@ # Internal static libraries LIBMPDEC_A= Modules/_decimal/libmpdec/libmpdec.a LIBEXPAT_A= Modules/expat/libexpat.a +LIBHACL_MD5_A= Modules/_hacl/libHacl_Hash_MD5.a +LIBHACL_SHA1_A= Modules/_hacl/libHacl_Hash_SHA1.a LIBHACL_SHA2_A= Modules/_hacl/libHacl_Hash_SHA2.a +LIBHACL_SHA3_A= Modules/_hacl/libHacl_Hash_SHA3.a LIBHACL_BLAKE2_A= Modules/_hacl/libHacl_Hash_Blake2.a +LIBHACL_HMAC_A= Modules/_hacl/libHacl_HMAC.a LIBHACL_CFLAGS=@LIBHACL_CFLAGS@ LIBHACL_SIMD128_FLAGS=@LIBHACL_SIMD128_FLAGS@ LIBHACL_SIMD256_FLAGS=@LIBHACL_SIMD256_FLAGS@ @@ -658,29 +662,61 @@ LIBEXPAT_HEADERS= \ ########################################################################## # hashlib's HACL* library +LIBHACL_MD5_OBJS= \ + Modules/_hacl/Hacl_Hash_MD5.o + +LIBHACL_SHA1_OBJS= \ + Modules/_hacl/Hacl_Hash_SHA1.o + LIBHACL_SHA2_OBJS= \ - Modules/_hacl/Hacl_Hash_SHA2.o + Modules/_hacl/Hacl_Hash_SHA2.o + +LIBHACL_SHA3_OBJS= \ + Modules/_hacl/Hacl_Hash_SHA3.o LIBHACL_BLAKE2_OBJS= \ - Modules/_hacl/Hacl_Hash_Blake2s.o \ - Modules/_hacl/Hacl_Hash_Blake2b.o \ - Modules/_hacl/Lib_Memzero0.o \ + Modules/_hacl/Hacl_Hash_Blake2s.o \ + Modules/_hacl/Hacl_Hash_Blake2b.o \ + Modules/_hacl/Lib_Memzero0.o \ $(LIBHACL_SIMD128_OBJS) \ $(LIBHACL_SIMD256_OBJS) +LIBHACL_HMAC_OBJS= \ + Modules/_hacl/Hacl_HMAC.o \ + $(LIBHACL_MD5_OBJS) \ + $(LIBHACL_SHA1_OBJS) \ + $(LIBHACL_SHA2_OBJS) \ + $(LIBHACL_SHA3_OBJS) \ + $(LIBHACL_BLAKE2_OBJS) + LIBHACL_HEADERS= \ - Modules/_hacl/include/krml/FStar_UInt128_Verified.h \ - Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h \ - Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h \ - Modules/_hacl/include/krml/internal/target.h \ - Modules/_hacl/include/krml/lowstar_endianness.h \ - Modules/_hacl/include/krml/types.h \ + Modules/_hacl/include/krml/FStar_UInt128_Verified.h \ + Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h \ + Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h \ + Modules/_hacl/include/krml/internal/target.h \ + Modules/_hacl/include/krml/lowstar_endianness.h \ + Modules/_hacl/include/krml/types.h \ Modules/_hacl/Hacl_Streaming_Types.h \ - Modules/_hacl/python_hacl_namespaces.h + Modules/_hacl/python_hacl_namespaces.h + +LIBHACL_MD5_HEADERS= \ + Modules/_hacl/Hacl_Hash_MD5.h \ + Modules/_hacl/internal/Hacl_Hash_MD5.h \ + $(LIBHACL_HEADERS) + +LIBHACL_SHA1_HEADERS= \ + Modules/_hacl/Hacl_Hash_SHA1.h \ + Modules/_hacl/internal/Hacl_Hash_SHA1.h \ + $(LIBHACL_HEADERS) LIBHACL_SHA2_HEADERS= \ - Modules/_hacl/Hacl_Hash_SHA2.h \ - Modules/_hacl/internal/Hacl_Hash_SHA2.h \ + Modules/_hacl/Hacl_Hash_SHA2.h \ + Modules/_hacl/internal/Hacl_Hash_SHA2.h \ + $(LIBHACL_HEADERS) + +LIBHACL_SHA3_HEADERS= \ + Modules/_hacl/Hacl_Hash_SHA3.h \ + Modules/_hacl/internal/Hacl_Hash_SHA3.h \ $(LIBHACL_HEADERS) LIBHACL_BLAKE2_HEADERS= \ @@ -695,6 +731,16 @@ LIBHACL_BLAKE2_HEADERS= \ Modules/_hacl/internal/Hacl_Hash_Blake2b_Simd256.h \ $(LIBHACL_HEADERS) +LIBHACL_HMAC_HEADERS= \ + Modules/_hacl/Hacl_HMAC.h \ + Modules/_hacl/internal/Hacl_HMAC.h \ + $(LIBHACL_MD5_HEADERS) \ + $(LIBHACL_SHA1_HEADERS) \ + $(LIBHACL_SHA2_HEADERS) \ + $(LIBHACL_SHA3_HEADERS) \ + $(LIBHACL_BLAKE2_HEADERS) \ + $(LIBHACL_HEADERS) + ######################################################################### # Rules @@ -1380,10 +1426,25 @@ $(LIBEXPAT_A): $(LIBEXPAT_OBJS) $(AR) $(ARFLAGS) $@ $(LIBEXPAT_OBJS) ########################################################################## -# Build HACL* static libraries for hashlib: libHacl_Hash_SHA2.a, and -# libHacl_Blake2.a -- the contents of the latter vary depending on whether we +# Build HACL* static libraries for hashlib and HACL* HMAC. +# +# The contents of libHacl_Blake2.a vary depending on whether we # have the ability to compile vectorized versions +Modules/_hacl/Hacl_Hash_MD5.o: $(srcdir)/Modules/_hacl/Hacl_Hash_MD5.c $(LIBHACL_MD5_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_MD5.c + +$(LIBHACL_MD5_A): $(LIBHACL_MD5_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_MD5_OBJS) + +Modules/_hacl/Hacl_Hash_SHA1.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA1.c $(LIBHACL_SHA1_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA1.c + +$(LIBHACL_SHA1_A): $(LIBHACL_SHA1_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA1_OBJS) + Modules/_hacl/Hacl_Hash_SHA2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA2.c $(LIBHACL_SHA2_HEADERS) $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA2.c @@ -1391,6 +1452,13 @@ $(LIBHACL_SHA2_A): $(LIBHACL_SHA2_OBJS) -rm -f $@ $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA2_OBJS) +Modules/_hacl/Hacl_Hash_SHA3.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA3.c $(LIBHACL_SHA3_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA3.c + +$(LIBHACL_SHA3_A): $(LIBHACL_SHA3_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA3_OBJS) + Modules/_hacl/Hacl_Hash_Blake2s.o: $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s.c $(LIBHACL_BLAKE2_HEADERS) $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_Blake2s.c @@ -1416,6 +1484,13 @@ $(LIBHACL_BLAKE2_A): $(LIBHACL_BLAKE2_OBJS) -rm -f $@ $(AR) $(ARFLAGS) $@ $(LIBHACL_BLAKE2_OBJS) +Modules/_hacl/Hacl_HMAC.o: $(srcdir)/Modules/_hacl/Hacl_HMAC.c $(LIBHACL_HMAC_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_HMAC.c + +$(LIBHACL_HMAC_A): $(LIBHACL_HMAC_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_HMAC_OBJS) + # create relative links from build/lib.platform/egg.so to Modules/egg.so # pybuilddir.txt is created too late. We cannot use it in Makefile # targets. ln --relative is not portable. @@ -3204,11 +3279,12 @@ MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@ MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@ MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h -MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_MD5.h Modules/_hacl/internal/Hacl_Hash_MD5.h Modules/_hacl/Hacl_Hash_MD5.c -MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA1.h Modules/_hacl/internal/Hacl_Hash_SHA1.h Modules/_hacl/Hacl_Hash_SHA1.c +MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_A) +MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_A) MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_A) -MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA3.h Modules/_hacl/internal/Hacl_Hash_SHA3.h Modules/_hacl/Hacl_Hash_SHA3.c +MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_A) MODULE__BLAKE2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_A) +MODULE__HMAC_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_A) MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/parts.h $(srcdir)/Modules/_testcapi/util.h diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index 739e005646ba97..cf1a385f6b6e76 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -295,6 +295,34 @@ ], "fileName": "Modules/expat/xmltok_ns.c" }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-HMAC.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c314722e89fefe2c00fb35b89f6eec7e03c336e6" + }, + { + "algorithm": "SHA256", + "checksumValue": "a3166efac8b34ea03fb61e7ce3a06cfab52adcccdac765c59eb3b0b848678ebf" + } + ], + "fileName": "Modules/_hacl/Hacl_HMAC.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-HMAC.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "397e27ce27de4f18a209033ed7f576a005a0c8c8" + }, + { + "algorithm": "SHA256", + "checksumValue": "b584dc409211857210c3444973cf84dc5efba7d29ca4ebdbe1305170ac5dfb73" + } + ], + "fileName": "Modules/_hacl/Hacl_HMAC.h" + }, { "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2b.c", "checksums": [ @@ -659,6 +687,20 @@ ], "fileName": "Modules/_hacl/include/krml/types.h" }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-internal-Hacl-HMAC.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "aef7c96186f1f5b5058b4ddffd3ccdd5d6e33669" + }, + { + "algorithm": "SHA256", + "checksumValue": "4d2ea32f3384513de59df04820bc09c4a3dd9b83aa8cd8e292981b5c19ac55c3" + } + ], + "fileName": "Modules/_hacl/internal/Hacl_HMAC.h" + }, { "SPDXID": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-Blake2b.h", "checksums": [ @@ -818,11 +860,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "37e3eb63c5c6f8ae671748bfde642c180b96d2de" + "checksumValue": "d707a40ab54dabab9958205005be3cb91b73a3da" }, { "algorithm": "SHA256", - "checksumValue": "0b5c7892cc25a2b3467936c1f346a6186d9d0a257d1bd5671beda253b66e0f68" + "checksumValue": "775bf3c0303b1228d404a864e20e3e283971a33ddd22c3e4592085b03f5ac460" } ], "fileName": "Modules/_hacl/python_hacl_namespaces.h" @@ -1808,6 +1850,16 @@ "relationshipType": "CONTAINS", "spdxElementId": "SPDXRef-PACKAGE-expat" }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-HMAC.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-HMAC.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, { "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-Blake2b.c", "relationshipType": "CONTAINS", @@ -1938,6 +1990,11 @@ "relationshipType": "CONTAINS", "spdxElementId": "SPDXRef-PACKAGE-hacl-star" }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-internal-Hacl-HMAC.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, { "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-Blake2b.h", "relationshipType": "CONTAINS", diff --git a/Modules/Setup b/Modules/Setup index ddf39e0b966610..f075571ab94577 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -165,11 +165,12 @@ PYTHONPATH=$(COREPYTHONPATH) #pyexpat pyexpat.c # hashing builtins -#_blake2 blake2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_Blake2.a -#_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE -#_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE -#_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a -#_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_blake2 blake2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_Blake2.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_md5 md5module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_MD5.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA1.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA3.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_hmac hmacmodule.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_HMAC.a -D_BSD_SOURCE -D_DEFAULT_SOURCE # text encodings and unicode #_codecs_cn cjkcodecs/_codecs_cn.c diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 52c0f883d383db..ea6b65a1071dcc 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -78,11 +78,11 @@ @MODULE_READLINE_TRUE@readline readline.c # hashing builtins, can be disabled with --without-builtin-hashlib-hashes -@MODULE__MD5_TRUE@_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE -@MODULE__SHA1_TRUE@_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE -@MODULE__SHA2_TRUE@_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a -@MODULE__SHA3_TRUE@_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE -@MODULE__BLAKE2_TRUE@_blake2 blake2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_Blake2.a +@MODULE__MD5_TRUE@_md5 md5module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_MD5.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +@MODULE__SHA1_TRUE@_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA1.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +@MODULE__SHA2_TRUE@_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +@MODULE__SHA3_TRUE@_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA3.a -D_BSD_SOURCE -D_DEFAULT_SOURCE +@MODULE__BLAKE2_TRUE@_blake2 blake2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_Blake2.a -D_BSD_SOURCE -D_DEFAULT_SOURCE ############################################################################ # XML and text @@ -142,6 +142,7 @@ @MODULE__SSL_TRUE@_ssl _ssl.c # needs -lcrypt @MODULE__HASHLIB_TRUE@_hashlib _hashopenssl.c +@MODULE__HMAC_TRUE@_hmac hmacmodule.c # Linux: -luuid, BSD/AIX: libc's uuid_create() @MODULE__UUID_TRUE@_uuid _uuidmodule.c diff --git a/Modules/_hacl/Hacl_HMAC.c b/Modules/_hacl/Hacl_HMAC.c new file mode 100644 index 00000000000000..2c32e403d88112 --- /dev/null +++ b/Modules/_hacl/Hacl_HMAC.c @@ -0,0 +1,1561 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "internal/Hacl_HMAC.h" + + +#include "internal/Hacl_Hash_SHA3.h" +#include "internal/Hacl_Hash_SHA2.h" +#include "internal/Hacl_Hash_SHA1.h" +#include "internal/Hacl_Hash_MD5.h" +#include "internal/Hacl_Hash_Blake2s.h" +#include "internal/Hacl_Hash_Blake2b.h" + +/** +Write the HMAC-MD5 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 byte. +`dst` must point to 16 bytes of memory. +*/ +void +Hacl_HMAC_compute_md5( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[64U]; + memset(key_block, 0U, 64U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 64U) + { + ite = key_len; + } + else + { + ite = 16U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 64U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_MD5_hash_oneshot(nkey, key, key_len); + } + uint8_t ipad[64U]; + memset(ipad, 0x36U, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[64U]; + memset(opad, 0x5cU, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint32_t s[4U] = { 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U }; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_MD5_update_last(s, 0ULL, ipad, 64U); + } + else + { + uint32_t block_len = 64U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_MD5_update_multi(s, ipad, 1U); + Hacl_Hash_MD5_update_multi(s, full_blocks, n_blocks); + Hacl_Hash_MD5_update_last(s, (uint64_t)64U + (uint64_t)full_blocks_len, rem, rem_len); + } + Hacl_Hash_MD5_finish(s, dst1); + uint8_t *hash1 = ipad; + Hacl_Hash_MD5_init(s); + uint32_t block_len = 64U; + uint32_t n_blocks0 = 16U / block_len; + uint32_t rem0 = 16U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 16U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_MD5_update_multi(s, opad, 1U); + Hacl_Hash_MD5_update_multi(s, full_blocks, n_blocks); + Hacl_Hash_MD5_update_last(s, (uint64_t)64U + (uint64_t)full_blocks_len, rem, rem_len); + Hacl_Hash_MD5_finish(s, dst); +} + +/** +Write the HMAC-SHA-1 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 byte. +`dst` must point to 20 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha1( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[64U]; + memset(key_block, 0U, 64U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 64U) + { + ite = key_len; + } + else + { + ite = 20U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 64U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA1_hash_oneshot(nkey, key, key_len); + } + uint8_t ipad[64U]; + memset(ipad, 0x36U, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[64U]; + memset(opad, 0x5cU, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint32_t s[5U] = { 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U }; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA1_update_last(s, 0ULL, ipad, 64U); + } + else + { + uint32_t block_len = 64U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA1_update_multi(s, ipad, 1U); + Hacl_Hash_SHA1_update_multi(s, full_blocks, n_blocks); + Hacl_Hash_SHA1_update_last(s, (uint64_t)64U + (uint64_t)full_blocks_len, rem, rem_len); + } + Hacl_Hash_SHA1_finish(s, dst1); + uint8_t *hash1 = ipad; + Hacl_Hash_SHA1_init(s); + uint32_t block_len = 64U; + uint32_t n_blocks0 = 20U / block_len; + uint32_t rem0 = 20U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 20U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA1_update_multi(s, opad, 1U); + Hacl_Hash_SHA1_update_multi(s, full_blocks, n_blocks); + Hacl_Hash_SHA1_update_last(s, (uint64_t)64U + (uint64_t)full_blocks_len, rem, rem_len); + Hacl_Hash_SHA1_finish(s, dst); +} + +/** +Write the HMAC-SHA-2-224 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 28 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_224( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[64U]; + memset(key_block, 0U, 64U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 64U) + { + ite = key_len; + } + else + { + ite = 28U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 64U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA2_hash_224(nkey, key, key_len); + } + uint8_t ipad[64U]; + memset(ipad, 0x36U, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[64U]; + memset(opad, 0x5cU, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint32_t st[8U] = { 0U }; + KRML_MAYBE_FOR8(i, + 0U, + 8U, + 1U, + uint32_t *os = st; + uint32_t x = Hacl_Hash_SHA2_h224[i]; + os[i] = x;); + uint32_t *s = st; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA2_sha224_update_last(0ULL + (uint64_t)64U, 64U, ipad, s); + } + else + { + uint32_t block_len = 64U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA2_sha224_update_nblocks(64U, ipad, s); + Hacl_Hash_SHA2_sha224_update_nblocks(n_blocks * 64U, full_blocks, s); + Hacl_Hash_SHA2_sha224_update_last((uint64_t)64U + (uint64_t)full_blocks_len + (uint64_t)rem_len, + rem_len, + rem, + s); + } + Hacl_Hash_SHA2_sha224_finish(s, dst1); + uint8_t *hash1 = ipad; + Hacl_Hash_SHA2_sha224_init(s); + uint32_t block_len = 64U; + uint32_t n_blocks0 = 28U / block_len; + uint32_t rem0 = 28U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 28U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA2_sha224_update_nblocks(64U, opad, s); + Hacl_Hash_SHA2_sha224_update_nblocks(n_blocks * 64U, full_blocks, s); + Hacl_Hash_SHA2_sha224_update_last((uint64_t)64U + (uint64_t)full_blocks_len + (uint64_t)rem_len, + rem_len, + rem, + s); + Hacl_Hash_SHA2_sha224_finish(s, dst); +} + +/** +Write the HMAC-SHA-2-256 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 32 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_256( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[64U]; + memset(key_block, 0U, 64U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 64U) + { + ite = key_len; + } + else + { + ite = 32U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 64U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA2_hash_256(nkey, key, key_len); + } + uint8_t ipad[64U]; + memset(ipad, 0x36U, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[64U]; + memset(opad, 0x5cU, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint32_t st[8U] = { 0U }; + KRML_MAYBE_FOR8(i, + 0U, + 8U, + 1U, + uint32_t *os = st; + uint32_t x = Hacl_Hash_SHA2_h256[i]; + os[i] = x;); + uint32_t *s = st; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA2_sha256_update_last(0ULL + (uint64_t)64U, 64U, ipad, s); + } + else + { + uint32_t block_len = 64U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA2_sha256_update_nblocks(64U, ipad, s); + Hacl_Hash_SHA2_sha256_update_nblocks(n_blocks * 64U, full_blocks, s); + Hacl_Hash_SHA2_sha256_update_last((uint64_t)64U + (uint64_t)full_blocks_len + (uint64_t)rem_len, + rem_len, + rem, + s); + } + Hacl_Hash_SHA2_sha256_finish(s, dst1); + uint8_t *hash1 = ipad; + Hacl_Hash_SHA2_sha256_init(s); + uint32_t block_len = 64U; + uint32_t n_blocks0 = 32U / block_len; + uint32_t rem0 = 32U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 32U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA2_sha256_update_nblocks(64U, opad, s); + Hacl_Hash_SHA2_sha256_update_nblocks(n_blocks * 64U, full_blocks, s); + Hacl_Hash_SHA2_sha256_update_last((uint64_t)64U + (uint64_t)full_blocks_len + (uint64_t)rem_len, + rem_len, + rem, + s); + Hacl_Hash_SHA2_sha256_finish(s, dst); +} + +/** +Write the HMAC-SHA-2-384 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 48 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_384( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[128U]; + memset(key_block, 0U, 128U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 128U) + { + ite = key_len; + } + else + { + ite = 48U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 128U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA2_hash_384(nkey, key, key_len); + } + uint8_t ipad[128U]; + memset(ipad, 0x36U, 128U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 128U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[128U]; + memset(opad, 0x5cU, 128U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 128U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t st[8U] = { 0U }; + KRML_MAYBE_FOR8(i, + 0U, + 8U, + 1U, + uint64_t *os = st; + uint64_t x = Hacl_Hash_SHA2_h384[i]; + os[i] = x;); + uint64_t *s = st; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA2_sha384_update_last(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128(0ULL), + FStar_UInt128_uint64_to_uint128((uint64_t)128U)), + 128U, + ipad, + s); + } + else + { + uint32_t block_len = 128U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA2_sha384_update_nblocks(128U, ipad, s); + Hacl_Hash_SHA2_sha384_update_nblocks(n_blocks * 128U, full_blocks, s); + Hacl_Hash_SHA2_sha384_update_last(FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128((uint64_t)128U), + FStar_UInt128_uint64_to_uint128((uint64_t)full_blocks_len)), + FStar_UInt128_uint64_to_uint128((uint64_t)rem_len)), + rem_len, + rem, + s); + } + Hacl_Hash_SHA2_sha384_finish(s, dst1); + uint8_t *hash1 = ipad; + Hacl_Hash_SHA2_sha384_init(s); + uint32_t block_len = 128U; + uint32_t n_blocks0 = 48U / block_len; + uint32_t rem0 = 48U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 48U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA2_sha384_update_nblocks(128U, opad, s); + Hacl_Hash_SHA2_sha384_update_nblocks(n_blocks * 128U, full_blocks, s); + Hacl_Hash_SHA2_sha384_update_last(FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128((uint64_t)128U), + FStar_UInt128_uint64_to_uint128((uint64_t)full_blocks_len)), + FStar_UInt128_uint64_to_uint128((uint64_t)rem_len)), + rem_len, + rem, + s); + Hacl_Hash_SHA2_sha384_finish(s, dst); +} + +/** +Write the HMAC-SHA-2-512 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 64 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_512( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[128U]; + memset(key_block, 0U, 128U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 128U) + { + ite = key_len; + } + else + { + ite = 64U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 128U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA2_hash_512(nkey, key, key_len); + } + uint8_t ipad[128U]; + memset(ipad, 0x36U, 128U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 128U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[128U]; + memset(opad, 0x5cU, 128U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 128U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t st[8U] = { 0U }; + KRML_MAYBE_FOR8(i, + 0U, + 8U, + 1U, + uint64_t *os = st; + uint64_t x = Hacl_Hash_SHA2_h512[i]; + os[i] = x;); + uint64_t *s = st; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA2_sha512_update_last(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128(0ULL), + FStar_UInt128_uint64_to_uint128((uint64_t)128U)), + 128U, + ipad, + s); + } + else + { + uint32_t block_len = 128U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA2_sha512_update_nblocks(128U, ipad, s); + Hacl_Hash_SHA2_sha512_update_nblocks(n_blocks * 128U, full_blocks, s); + Hacl_Hash_SHA2_sha512_update_last(FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128((uint64_t)128U), + FStar_UInt128_uint64_to_uint128((uint64_t)full_blocks_len)), + FStar_UInt128_uint64_to_uint128((uint64_t)rem_len)), + rem_len, + rem, + s); + } + Hacl_Hash_SHA2_sha512_finish(s, dst1); + uint8_t *hash1 = ipad; + Hacl_Hash_SHA2_sha512_init(s); + uint32_t block_len = 128U; + uint32_t n_blocks0 = 64U / block_len; + uint32_t rem0 = 64U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 64U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA2_sha512_update_nblocks(128U, opad, s); + Hacl_Hash_SHA2_sha512_update_nblocks(n_blocks * 128U, full_blocks, s); + Hacl_Hash_SHA2_sha512_update_last(FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128((uint64_t)128U), + FStar_UInt128_uint64_to_uint128((uint64_t)full_blocks_len)), + FStar_UInt128_uint64_to_uint128((uint64_t)rem_len)), + rem_len, + rem, + s); + Hacl_Hash_SHA2_sha512_finish(s, dst); +} + +/** +Write the HMAC-SHA-3-224 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 144 bytes. +`dst` must point to 28 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_224( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[144U]; + memset(key_block, 0U, 144U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 144U) + { + ite = key_len; + } + else + { + ite = 28U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 144U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA3_sha3_224(nkey, key, key_len); + } + uint8_t ipad[144U]; + memset(ipad, 0x36U, 144U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 144U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[144U]; + memset(opad, 0x5cU, 144U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 144U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t s[25U] = { 0U }; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_224, s, ipad, 144U); + } + else + { + uint32_t block_len = 144U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_224, s, ipad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_224, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_224, s, rem, rem_len); + } + uint32_t remOut = 28U; + uint8_t hbuf0[256U] = { 0U }; + uint64_t ws0[32U] = { 0U }; + memcpy(ws0, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf0 + i * 8U, ws0[i]); + } + memcpy(dst1 + 28U - remOut, hbuf0, remOut * sizeof (uint8_t)); + uint8_t *hash1 = ipad; + memset(s, 0U, 25U * sizeof (uint64_t)); + uint32_t block_len = 144U; + uint32_t n_blocks0 = 28U / block_len; + uint32_t rem0 = 28U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 28U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_224, s, opad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_224, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_224, s, rem, rem_len); + uint32_t remOut0 = 28U; + uint8_t hbuf[256U] = { 0U }; + uint64_t ws[32U] = { 0U }; + memcpy(ws, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf + i * 8U, ws[i]); + } + memcpy(dst + 28U - remOut0, hbuf, remOut0 * sizeof (uint8_t)); +} + +/** +Write the HMAC-SHA-3-256 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 136 bytes. +`dst` must point to 32 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_256( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[136U]; + memset(key_block, 0U, 136U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 136U) + { + ite = key_len; + } + else + { + ite = 32U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 136U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA3_sha3_256(nkey, key, key_len); + } + uint8_t ipad[136U]; + memset(ipad, 0x36U, 136U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 136U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[136U]; + memset(opad, 0x5cU, 136U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 136U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t s[25U] = { 0U }; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_256, s, ipad, 136U); + } + else + { + uint32_t block_len = 136U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_256, s, ipad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_256, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_256, s, rem, rem_len); + } + uint32_t remOut = 32U; + uint8_t hbuf0[256U] = { 0U }; + uint64_t ws0[32U] = { 0U }; + memcpy(ws0, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf0 + i * 8U, ws0[i]); + } + memcpy(dst1 + 32U - remOut, hbuf0, remOut * sizeof (uint8_t)); + uint8_t *hash1 = ipad; + memset(s, 0U, 25U * sizeof (uint64_t)); + uint32_t block_len = 136U; + uint32_t n_blocks0 = 32U / block_len; + uint32_t rem0 = 32U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 32U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_256, s, opad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_256, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_256, s, rem, rem_len); + uint32_t remOut0 = 32U; + uint8_t hbuf[256U] = { 0U }; + uint64_t ws[32U] = { 0U }; + memcpy(ws, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf + i * 8U, ws[i]); + } + memcpy(dst + 32U - remOut0, hbuf, remOut0 * sizeof (uint8_t)); +} + +/** +Write the HMAC-SHA-3-384 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 104 bytes. +`dst` must point to 48 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_384( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[104U]; + memset(key_block, 0U, 104U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 104U) + { + ite = key_len; + } + else + { + ite = 48U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 104U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA3_sha3_384(nkey, key, key_len); + } + uint8_t ipad[104U]; + memset(ipad, 0x36U, 104U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 104U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[104U]; + memset(opad, 0x5cU, 104U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 104U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t s[25U] = { 0U }; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_384, s, ipad, 104U); + } + else + { + uint32_t block_len = 104U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_384, s, ipad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_384, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_384, s, rem, rem_len); + } + uint32_t remOut = 48U; + uint8_t hbuf0[256U] = { 0U }; + uint64_t ws0[32U] = { 0U }; + memcpy(ws0, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf0 + i * 8U, ws0[i]); + } + memcpy(dst1 + 48U - remOut, hbuf0, remOut * sizeof (uint8_t)); + uint8_t *hash1 = ipad; + memset(s, 0U, 25U * sizeof (uint64_t)); + uint32_t block_len = 104U; + uint32_t n_blocks0 = 48U / block_len; + uint32_t rem0 = 48U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 48U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_384, s, opad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_384, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_384, s, rem, rem_len); + uint32_t remOut0 = 48U; + uint8_t hbuf[256U] = { 0U }; + uint64_t ws[32U] = { 0U }; + memcpy(ws, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf + i * 8U, ws[i]); + } + memcpy(dst + 48U - remOut0, hbuf, remOut0 * sizeof (uint8_t)); +} + +/** +Write the HMAC-SHA-3-512 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 72 bytes. +`dst` must point to 64 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_512( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[72U]; + memset(key_block, 0U, 72U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 72U) + { + ite = key_len; + } + else + { + ite = 64U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 72U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_SHA3_sha3_512(nkey, key, key_len); + } + uint8_t ipad[72U]; + memset(ipad, 0x36U, 72U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 72U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[72U]; + memset(opad, 0x5cU, 72U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 72U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t s[25U] = { 0U }; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_512, s, ipad, 72U); + } + else + { + uint32_t block_len = 72U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_512, s, ipad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_512, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_512, s, rem, rem_len); + } + uint32_t remOut = 64U; + uint8_t hbuf0[256U] = { 0U }; + uint64_t ws0[32U] = { 0U }; + memcpy(ws0, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf0 + i * 8U, ws0[i]); + } + memcpy(dst1 + 64U - remOut, hbuf0, remOut * sizeof (uint8_t)); + uint8_t *hash1 = ipad; + memset(s, 0U, 25U * sizeof (uint64_t)); + uint32_t block_len = 72U; + uint32_t n_blocks0 = 64U / block_len; + uint32_t rem0 = 64U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 64U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_512, s, opad, 1U); + Hacl_Hash_SHA3_update_multi_sha3(Spec_Hash_Definitions_SHA3_512, s, full_blocks, n_blocks); + Hacl_Hash_SHA3_update_last_sha3(Spec_Hash_Definitions_SHA3_512, s, rem, rem_len); + uint32_t remOut0 = 64U; + uint8_t hbuf[256U] = { 0U }; + uint64_t ws[32U] = { 0U }; + memcpy(ws, s, 25U * sizeof (uint64_t)); + for (uint32_t i = 0U; i < 32U; i++) + { + store64_le(hbuf + i * 8U, ws[i]); + } + memcpy(dst + 64U - remOut0, hbuf, remOut0 * sizeof (uint8_t)); +} + +/** +Write the HMAC-BLAKE2s MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 32 bytes of memory. +*/ +void +Hacl_HMAC_compute_blake2s_32( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[64U]; + memset(key_block, 0U, 64U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 64U) + { + ite = key_len; + } + else + { + ite = 32U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 64U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_Blake2s_hash_with_key(nkey, 32U, key, key_len, NULL, 0U); + } + uint8_t ipad[64U]; + memset(ipad, 0x36U, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[64U]; + memset(opad, 0x5cU, 64U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 64U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint32_t s[16U] = { 0U }; + Hacl_Hash_Blake2s_init(s, 0U, 32U); + uint32_t *s0 = s; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + uint32_t wv[16U] = { 0U }; + Hacl_Hash_Blake2s_update_last(64U, wv, s0, false, 0ULL, 64U, ipad); + } + else + { + uint32_t block_len = 64U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + uint32_t wv[16U] = { 0U }; + Hacl_Hash_Blake2s_update_multi(64U, wv, s0, 0ULL, ipad, 1U); + uint32_t wv0[16U] = { 0U }; + Hacl_Hash_Blake2s_update_multi(n_blocks * 64U, + wv0, + s0, + (uint64_t)block_len, + full_blocks, + n_blocks); + uint32_t wv1[16U] = { 0U }; + Hacl_Hash_Blake2s_update_last(rem_len, + wv1, + s0, + false, + (uint64_t)64U + (uint64_t)full_blocks_len, + rem_len, + rem); + } + Hacl_Hash_Blake2s_finish(32U, dst1, s0); + uint8_t *hash1 = ipad; + Hacl_Hash_Blake2s_init(s0, 0U, 32U); + uint32_t block_len = 64U; + uint32_t n_blocks0 = 32U / block_len; + uint32_t rem0 = 32U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 32U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + uint32_t wv[16U] = { 0U }; + Hacl_Hash_Blake2s_update_multi(64U, wv, s0, 0ULL, opad, 1U); + uint32_t wv0[16U] = { 0U }; + Hacl_Hash_Blake2s_update_multi(n_blocks * 64U, + wv0, + s0, + (uint64_t)block_len, + full_blocks, + n_blocks); + uint32_t wv1[16U] = { 0U }; + Hacl_Hash_Blake2s_update_last(rem_len, + wv1, + s0, + false, + (uint64_t)64U + (uint64_t)full_blocks_len, + rem_len, + rem); + Hacl_Hash_Blake2s_finish(32U, dst, s0); +} + +/** +Write the HMAC-BLAKE2b MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 64 bytes of memory. +*/ +void +Hacl_HMAC_compute_blake2b_32( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +) +{ + uint8_t key_block[128U]; + memset(key_block, 0U, 128U * sizeof (uint8_t)); + uint8_t *nkey = key_block; + uint32_t ite; + if (key_len <= 128U) + { + ite = key_len; + } + else + { + ite = 64U; + } + uint8_t *zeroes = key_block + ite; + KRML_MAYBE_UNUSED_VAR(zeroes); + if (key_len <= 128U) + { + memcpy(nkey, key, key_len * sizeof (uint8_t)); + } + else + { + Hacl_Hash_Blake2b_hash_with_key(nkey, 64U, key, key_len, NULL, 0U); + } + uint8_t ipad[128U]; + memset(ipad, 0x36U, 128U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 128U; i++) + { + uint8_t xi = ipad[i]; + uint8_t yi = key_block[i]; + ipad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint8_t opad[128U]; + memset(opad, 0x5cU, 128U * sizeof (uint8_t)); + for (uint32_t i = 0U; i < 128U; i++) + { + uint8_t xi = opad[i]; + uint8_t yi = key_block[i]; + opad[i] = (uint32_t)xi ^ (uint32_t)yi; + } + uint64_t s[16U] = { 0U }; + Hacl_Hash_Blake2b_init(s, 0U, 64U); + uint64_t *s0 = s; + uint8_t *dst1 = ipad; + if (data_len == 0U) + { + uint64_t wv[16U] = { 0U }; + Hacl_Hash_Blake2b_update_last(128U, + wv, + s0, + false, + FStar_UInt128_uint64_to_uint128(0ULL), + 128U, + ipad); + } + else + { + uint32_t block_len = 128U; + uint32_t n_blocks0 = data_len / block_len; + uint32_t rem0 = data_len % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = data_len - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = data; + uint8_t *rem = data + full_blocks_len; + uint64_t wv[16U] = { 0U }; + Hacl_Hash_Blake2b_update_multi(128U, wv, s0, FStar_UInt128_uint64_to_uint128(0ULL), ipad, 1U); + uint64_t wv0[16U] = { 0U }; + Hacl_Hash_Blake2b_update_multi(n_blocks * 128U, + wv0, + s0, + FStar_UInt128_uint64_to_uint128((uint64_t)block_len), + full_blocks, + n_blocks); + uint64_t wv1[16U] = { 0U }; + Hacl_Hash_Blake2b_update_last(rem_len, + wv1, + s0, + false, + FStar_UInt128_add(FStar_UInt128_uint64_to_uint128((uint64_t)128U), + FStar_UInt128_uint64_to_uint128((uint64_t)full_blocks_len)), + rem_len, + rem); + } + Hacl_Hash_Blake2b_finish(64U, dst1, s0); + uint8_t *hash1 = ipad; + Hacl_Hash_Blake2b_init(s0, 0U, 64U); + uint32_t block_len = 128U; + uint32_t n_blocks0 = 64U / block_len; + uint32_t rem0 = 64U % block_len; + K___uint32_t_uint32_t scrut; + if (n_blocks0 > 0U && rem0 == 0U) + { + uint32_t n_blocks_ = n_blocks0 - 1U; + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks_, .snd = 64U - n_blocks_ * block_len }); + } + else + { + scrut = ((K___uint32_t_uint32_t){ .fst = n_blocks0, .snd = rem0 }); + } + uint32_t n_blocks = scrut.fst; + uint32_t rem_len = scrut.snd; + uint32_t full_blocks_len = n_blocks * block_len; + uint8_t *full_blocks = hash1; + uint8_t *rem = hash1 + full_blocks_len; + uint64_t wv[16U] = { 0U }; + Hacl_Hash_Blake2b_update_multi(128U, wv, s0, FStar_UInt128_uint64_to_uint128(0ULL), opad, 1U); + uint64_t wv0[16U] = { 0U }; + Hacl_Hash_Blake2b_update_multi(n_blocks * 128U, + wv0, + s0, + FStar_UInt128_uint64_to_uint128((uint64_t)block_len), + full_blocks, + n_blocks); + uint64_t wv1[16U] = { 0U }; + Hacl_Hash_Blake2b_update_last(rem_len, + wv1, + s0, + false, + FStar_UInt128_add(FStar_UInt128_uint64_to_uint128((uint64_t)128U), + FStar_UInt128_uint64_to_uint128((uint64_t)full_blocks_len)), + rem_len, + rem); + Hacl_Hash_Blake2b_finish(64U, dst, s0); +} + diff --git a/Modules/_hacl/Hacl_HMAC.h b/Modules/_hacl/Hacl_HMAC.h new file mode 100644 index 00000000000000..6feb51a88626c9 --- /dev/null +++ b/Modules/_hacl/Hacl_HMAC.h @@ -0,0 +1,231 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __Hacl_HMAC_H +#define __Hacl_HMAC_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include "python_hacl_namespaces.h" +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "Hacl_Streaming_Types.h" + +#include "Hacl_Hash_SHA3.h" +#include "Hacl_Hash_SHA2.h" +#include "Hacl_Hash_Blake2s.h" +#include "Hacl_Hash_Blake2b.h" + +/** +Write the HMAC-MD5 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 byte. +`dst` must point to 16 bytes of memory. +*/ +void +Hacl_HMAC_compute_md5( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-1 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 byte. +`dst` must point to 20 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha1( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-2-224 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 28 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_224( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-2-256 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 32 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_256( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-2-384 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 48 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_384( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-2-512 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 64 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha2_512( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-3-224 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 144 bytes. +`dst` must point to 28 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_224( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-3-256 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 136 bytes. +`dst` must point to 32 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_256( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-3-384 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 104 bytes. +`dst` must point to 48 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_384( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-SHA-3-512 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 72 bytes. +`dst` must point to 64 bytes of memory. +*/ +void +Hacl_HMAC_compute_sha3_512( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-BLAKE2s MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 32 bytes of memory. +*/ +void +Hacl_HMAC_compute_blake2s_32( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +/** +Write the HMAC-BLAKE2b MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 64 bytes of memory. +*/ +void +Hacl_HMAC_compute_blake2b_32( + uint8_t *dst, + uint8_t *key, + uint32_t key_len, + uint8_t *data, + uint32_t data_len +); + +#if defined(__cplusplus) +} +#endif + +#define __Hacl_HMAC_H_DEFINED +#endif diff --git a/Modules/_hacl/README.md b/Modules/_hacl/README.md index e6a156a54b3cee..0d6454cdd6efb3 100644 --- a/Modules/_hacl/README.md +++ b/Modules/_hacl/README.md @@ -8,10 +8,10 @@ safety, functional correctness, and secret independence. ## Updating HACL* -Use the `refresh.sh` script in this directory to pull in a new upstream code -version. The upstream git hash used for the most recent code pull is recorded -in the script. Modify the script as needed to bring in more if changes are -needed based on upstream code refactoring. +Use the [refresh.sh](refresh.sh) script in this directory to pull in a new +upstream code version. The upstream git hash used for the most recent code +pull is recorded in the script. Modify the script as needed to bring in more +if changes are needed based on upstream code refactoring. Never manually edit HACL\* files. Always add transformation shell code to the `refresh.sh` script to perform any necessary edits. If there are serious code @@ -19,9 +19,9 @@ changes needed, work with the upstream repository. ## Local files -1. `./include/python_hacl_namespaces.h` -1. `./README.md` -1. `./refresh.sh` +* [python_hacl_namespaces.h](python_hacl_namespaces.h) +* [README.md](README.md) +* [refresh.sh](refresh.sh) ## ACKS diff --git a/Modules/_hacl/internal/Hacl_HMAC.h b/Modules/_hacl/internal/Hacl_HMAC.h new file mode 100644 index 00000000000000..5038a6cf224a70 --- /dev/null +++ b/Modules/_hacl/internal/Hacl_HMAC.h @@ -0,0 +1,59 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __internal_Hacl_HMAC_H +#define __internal_Hacl_HMAC_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + + +#include "internal/Hacl_Hash_SHA3.h" +#include "internal/Hacl_Hash_SHA2.h" +#include "internal/Hacl_Hash_SHA1.h" +#include "internal/Hacl_Hash_MD5.h" +#include "internal/Hacl_Hash_Blake2s.h" +#include "internal/Hacl_Hash_Blake2b.h" +#include "../Hacl_HMAC.h" + +typedef struct K___uint32_t_uint32_t_s +{ + uint32_t fst; + uint32_t snd; +} +K___uint32_t_uint32_t; + +#if defined(__cplusplus) +} +#endif + +#define __internal_Hacl_HMAC_H_DEFINED +#endif diff --git a/Modules/_hacl/python_hacl_namespaces.h b/Modules/_hacl/python_hacl_namespaces.h index 8a1f4aef384d62..acb0e34e8963d8 100644 --- a/Modules/_hacl/python_hacl_namespaces.h +++ b/Modules/_hacl/python_hacl_namespaces.h @@ -209,4 +209,22 @@ #define Hacl_Hash_SHA3_state_free python_hashlib_Hacl_Hash_SHA3_state_free #define Hacl_Hash_SHA3_state_malloc python_hashlib_Hacl_Hash_SHA3_state_malloc +// HMAC-MD5 +#define Hacl_HMAC_compute_md5 python_hashlib_Hacl_HMAC_compute_md5 +// HMAC-SHA-1 +#define Hacl_HMAC_compute_sha1 python_hashlib_Hacl_HMAC_compute_sha1 +// HMAC-SHA-2 +#define Hacl_HMAC_compute_sha2_224 python_hashlib_Hacl_HMAC_compute_sha2_224 +#define Hacl_HMAC_compute_sha2_256 python_hashlib_Hacl_HMAC_compute_sha2_256 +#define Hacl_HMAC_compute_sha2_384 python_hashlib_Hacl_HMAC_compute_sha2_384 +#define Hacl_HMAC_compute_sha2_512 python_hashlib_Hacl_HMAC_compute_sha2_512 +// HMAC-SHA-3 +#define Hacl_HMAC_compute_sha3_224 python_hashlib_Hacl_HMAC_compute_sha3_224 +#define Hacl_HMAC_compute_sha3_256 python_hashlib_Hacl_HMAC_compute_sha3_256 +#define Hacl_HMAC_compute_sha3_384 python_hashlib_Hacl_HMAC_compute_sha3_384 +#define Hacl_HMAC_compute_sha3_512 python_hashlib_Hacl_HMAC_compute_sha3_512 +// HMAC-BLAKE +#define Hacl_HMAC_compute_blake2s_32 python_hashlib_Hacl_HMAC_compute_blake2s_32 +#define Hacl_HMAC_compute_blake2b_32 python_hashlib_Hacl_HMAC_compute_blake2b_32 + #endif // _PYTHON_HACL_NAMESPACES_H diff --git a/Modules/_hacl/refresh.sh b/Modules/_hacl/refresh.sh index 4147ab302fe146..3b83da9ad29347 100755 --- a/Modules/_hacl/refresh.sh +++ b/Modules/_hacl/refresh.sh @@ -41,6 +41,7 @@ fi declare -a dist_files dist_files=( Hacl_Streaming_Types.h +# Cryptographic Hash Functions (headers) Hacl_Hash_MD5.h Hacl_Hash_SHA1.h Hacl_Hash_SHA2.h @@ -49,6 +50,9 @@ dist_files=( Hacl_Hash_Blake2s.h Hacl_Hash_Blake2b_Simd256.h Hacl_Hash_Blake2s_Simd128.h +# Cryptographic Primitives (headers) + Hacl_HMAC.h +# Cryptographic Hash Functions (internal headers) internal/Hacl_Hash_MD5.h internal/Hacl_Hash_SHA1.h internal/Hacl_Hash_SHA2.h @@ -58,6 +62,9 @@ dist_files=( internal/Hacl_Hash_Blake2b_Simd256.h internal/Hacl_Hash_Blake2s_Simd128.h internal/Hacl_Impl_Blake2_Constants.h +# Cryptographic Primitives (internal headers) + internal/Hacl_HMAC.h +# Cryptographic Hash Functions (sources) Hacl_Hash_MD5.c Hacl_Hash_SHA1.c Hacl_Hash_SHA2.c @@ -66,6 +73,9 @@ dist_files=( Hacl_Hash_Blake2s.c Hacl_Hash_Blake2b_Simd256.c Hacl_Hash_Blake2s_Simd128.c +# Cryptographic Primitives (sources) + Hacl_HMAC.c +# Miscellaneous libintvector.h lib_memzero0.h Lib_Memzero0.c @@ -143,7 +153,9 @@ $sed -i -z 's!\(extern\|typedef\)[^;]*;\n\n!!g' include/krml/FStar_UInt_8_16_32_ $sed -i 's!#include.*Hacl_Krmllib.h"!!g' "${all_files[@]}" # Use globally unique names for the Hacl_ C APIs to avoid linkage conflicts. -$sed -i -z 's!#include \n!#include \n#include "python_hacl_namespaces.h"\n!' Hacl_Hash_*.h +$sed -i -z 's!#include \n!#include \n#include "python_hacl_namespaces.h"\n!' \ + Hacl_Hash_*.h \ + Hacl_HMAC.h # Finally, we remove a bunch of ifdefs from target.h that are, again, useful in # the general case, but not exercised by the subset of HACL* that we vendor. diff --git a/Modules/clinic/hmacmodule.c.h b/Modules/clinic/hmacmodule.c.h new file mode 100644 index 00000000000000..dc3fdd655ccd9f --- /dev/null +++ b/Modules/clinic/hmacmodule.c.h @@ -0,0 +1,386 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + +PyDoc_STRVAR(_hmac_compute_digest__doc__, +"compute_digest($module, key, msg, digestmod, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_DIGEST_METHODDEF \ + {"compute_digest", _PyCFunction_CAST(_hmac_compute_digest), METH_FASTCALL, _hmac_compute_digest__doc__}, + +static PyObject * +_hmac_compute_digest_impl(PyObject *module, PyObject *key, PyObject *msg, + PyObject *digestmod); + +static PyObject * +_hmac_compute_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + PyObject *digestmod; + + if (!_PyArg_CheckPositional("compute_digest", nargs, 3, 3)) { + goto exit; + } + key = args[0]; + msg = args[1]; + digestmod = args[2]; + return_value = _hmac_compute_digest_impl(module, key, msg, digestmod); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_md5__doc__, +"compute_md5($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_MD5_METHODDEF \ + {"compute_md5", _PyCFunction_CAST(_hmac_compute_md5), METH_FASTCALL, _hmac_compute_md5__doc__}, + +static PyObject * +_hmac_compute_md5_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_md5", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_md5_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha1__doc__, +"compute_sha1($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA1_METHODDEF \ + {"compute_sha1", _PyCFunction_CAST(_hmac_compute_sha1), METH_FASTCALL, _hmac_compute_sha1__doc__}, + +static PyObject * +_hmac_compute_sha1_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha1", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha1_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha2_224__doc__, +"compute_sha2_224($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA2_224_METHODDEF \ + {"compute_sha2_224", _PyCFunction_CAST(_hmac_compute_sha2_224), METH_FASTCALL, _hmac_compute_sha2_224__doc__}, + +static PyObject * +_hmac_compute_sha2_224_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha2_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha2_224", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha2_224_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha2_256__doc__, +"compute_sha2_256($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA2_256_METHODDEF \ + {"compute_sha2_256", _PyCFunction_CAST(_hmac_compute_sha2_256), METH_FASTCALL, _hmac_compute_sha2_256__doc__}, + +static PyObject * +_hmac_compute_sha2_256_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha2_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha2_256", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha2_256_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha2_384__doc__, +"compute_sha2_384($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA2_384_METHODDEF \ + {"compute_sha2_384", _PyCFunction_CAST(_hmac_compute_sha2_384), METH_FASTCALL, _hmac_compute_sha2_384__doc__}, + +static PyObject * +_hmac_compute_sha2_384_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha2_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha2_384", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha2_384_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha2_512__doc__, +"compute_sha2_512($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA2_512_METHODDEF \ + {"compute_sha2_512", _PyCFunction_CAST(_hmac_compute_sha2_512), METH_FASTCALL, _hmac_compute_sha2_512__doc__}, + +static PyObject * +_hmac_compute_sha2_512_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha2_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha2_512", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha2_512_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha3_224__doc__, +"compute_sha3_224($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA3_224_METHODDEF \ + {"compute_sha3_224", _PyCFunction_CAST(_hmac_compute_sha3_224), METH_FASTCALL, _hmac_compute_sha3_224__doc__}, + +static PyObject * +_hmac_compute_sha3_224_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha3_224", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha3_224_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha3_256__doc__, +"compute_sha3_256($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA3_256_METHODDEF \ + {"compute_sha3_256", _PyCFunction_CAST(_hmac_compute_sha3_256), METH_FASTCALL, _hmac_compute_sha3_256__doc__}, + +static PyObject * +_hmac_compute_sha3_256_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha3_256", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha3_256_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha3_384__doc__, +"compute_sha3_384($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA3_384_METHODDEF \ + {"compute_sha3_384", _PyCFunction_CAST(_hmac_compute_sha3_384), METH_FASTCALL, _hmac_compute_sha3_384__doc__}, + +static PyObject * +_hmac_compute_sha3_384_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha3_384", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha3_384_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_sha3_512__doc__, +"compute_sha3_512($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_SHA3_512_METHODDEF \ + {"compute_sha3_512", _PyCFunction_CAST(_hmac_compute_sha3_512), METH_FASTCALL, _hmac_compute_sha3_512__doc__}, + +static PyObject * +_hmac_compute_sha3_512_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_sha3_512", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_sha3_512_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_blake2s_32__doc__, +"compute_blake2s_32($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_BLAKE2S_32_METHODDEF \ + {"compute_blake2s_32", _PyCFunction_CAST(_hmac_compute_blake2s_32), METH_FASTCALL, _hmac_compute_blake2s_32__doc__}, + +static PyObject * +_hmac_compute_blake2s_32_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_blake2s_32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_blake2s_32", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_blake2s_32_impl(module, key, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hmac_compute_blake2b_32__doc__, +"compute_blake2b_32($module, key, msg, /)\n" +"--\n" +"\n"); + +#define _HMAC_COMPUTE_BLAKE2B_32_METHODDEF \ + {"compute_blake2b_32", _PyCFunction_CAST(_hmac_compute_blake2b_32), METH_FASTCALL, _hmac_compute_blake2b_32__doc__}, + +static PyObject * +_hmac_compute_blake2b_32_impl(PyObject *module, PyObject *key, PyObject *msg); + +static PyObject * +_hmac_compute_blake2b_32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *msg; + + if (!_PyArg_CheckPositional("compute_blake2b_32", nargs, 2, 2)) { + goto exit; + } + key = args[0]; + msg = args[1]; + return_value = _hmac_compute_blake2b_32_impl(module, key, msg); + +exit: + return return_value; +} +/*[clinic end generated code: output=f0d13237cf250e7d input=a9049054013a1b77]*/ diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c new file mode 100644 index 00000000000000..0d8be53dda81c9 --- /dev/null +++ b/Modules/hmacmodule.c @@ -0,0 +1,968 @@ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" +#include "pycore_hashtable.h" + +#include // EVP_* interface +#include // LN_* and NID_* macros + +#include "_hacl/Hacl_HMAC.h" +#include "hashlib.h" + +// --- OpenSSL EVP interface (used for resolving algorithm names) ------------- + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# define Py_EVP_MD EVP_MD +# define Py_EVP_MD_fetch(ALGO) EVP_MD_fetch(NULL, ALGO, NULL) +# define Py_EVP_MD_free(MD) EVP_MD_free(MD) +#else +# define Py_EVP_MD const EVP_MD +# define Py_EVP_MD_fetch(ALGO) EVP_get_digestbyname(ALGO) +# define Py_EVP_MD_free(MD) do {} while(0) +#endif + +// --- HMAC underlying hash function static information ----------------------- + +#define Py_hmac_hash_max_digest_size 64 + +#define Py_OpenSSL_LN_MISSING NULL +#define Py_OpenSSL_NID_MISSING -1 + +/* MD-5 */ +// HACL_HID = md5 +#define Py_hmac_md5_block_size 64 +#define Py_hmac_md5_digest_size 16 + +#define Py_hmac_md5_compute_func Hacl_HMAC_compute_md5 + +#define Py_OpenSSL_LN_md5 LN_md5 +#define Py_OpenSSL_NID_md5 NID_md5 + +/* SHA-1 family */ +// HACL_HID = sha1 +#define Py_hmac_sha1_block_size 64 +#define Py_hmac_sha1_digest_size 20 + +#define Py_hmac_sha1_compute_func Hacl_HMAC_compute_sha1 + +#define Py_OpenSSL_LN_sha1 LN_sha1 +#define Py_OpenSSL_NID_sha1 NID_sha1 + +/* SHA-2 family */ +// HACL_HID = sha2_224 +#define Py_hmac_sha2_224_block_size 64 +#define Py_hmac_sha2_224_digest_size 28 + +#define Py_hmac_sha2_224_compute_func Hacl_HMAC_compute_sha2_224 + +#define Py_OpenSSL_LN_sha2_224 LN_sha224 +#define Py_OpenSSL_NID_sha2_224 NID_sha224 + +// HACL_HID = sha2_256 +#define Py_hmac_sha2_256_block_size 64 +#define Py_hmac_sha2_256_digest_size 32 + +#define Py_hmac_sha2_256_compute_func Hacl_HMAC_compute_sha2_256 + +#define Py_OpenSSL_LN_sha2_256 LN_sha256 +#define Py_OpenSSL_NID_sha2_256 NID_sha256 + +// HACL_HID = sha2_384 +#define Py_hmac_sha2_384_block_size 128 +#define Py_hmac_sha2_384_digest_size 48 + +#define Py_hmac_sha2_384_compute_func Hacl_HMAC_compute_sha2_384 + +#define Py_OpenSSL_LN_sha2_384 LN_sha384 +#define Py_OpenSSL_NID_sha2_384 NID_sha384 + +// HACL_HID = sha2_512 +#define Py_hmac_sha2_512_block_size 128 +#define Py_hmac_sha2_512_digest_size 64 + +#define Py_hmac_sha2_512_compute_func Hacl_HMAC_compute_sha2_512 + +#define Py_OpenSSL_LN_sha2_512 LN_sha512 +#define Py_OpenSSL_NID_sha2_512 NID_sha512 + +/* SHA-3 family */ +// HACL_HID = sha3_224 +#define Py_hmac_sha3_224_block_size 144 +#define Py_hmac_sha3_224_digest_size 28 + +#define Py_hmac_sha3_224_compute_func Hacl_HMAC_compute_sha3_224 + +#if defined(LN_sha3_224) && defined(NID_sha3_224) +# define Py_OpenSSL_LN_sha3_224 LN_sha3_224 +# define Py_OpenSSL_NID_sha3_224 NID_sha3_224 +#else +# define Py_OpenSSL_LN_sha3_224 Py_OpenSSL_LN_MISSING +# define Py_OpenSSL_NID_sha3_224 Py_OpenSSL_NID_MISSING +#endif + +// HACL_HID = sha3_256 +#define Py_hmac_sha3_256_block_size 136 +#define Py_hmac_sha3_256_digest_size 32 + +#define Py_hmac_sha3_256_compute_func Hacl_HMAC_compute_sha3_256 + +#if defined(LN_sha3_256) && defined(NID_sha3_256) +# define Py_OpenSSL_LN_sha3_256 LN_sha3_256 +# define Py_OpenSSL_NID_sha3_256 NID_sha3_256 +#else +# define Py_OpenSSL_LN_sha3_256 Py_OpenSSL_LN_MISSING +# define Py_OpenSSL_NID_sha3_256 Py_OpenSSL_NID_MISSING +#endif + +// HACL_HID = sha3_384 +#define Py_hmac_sha3_384_block_size 104 +#define Py_hmac_sha3_384_digest_size 48 + +#define Py_hmac_sha3_384_compute_func Hacl_HMAC_compute_sha3_384 + +#if defined(LN_sha3_384) && defined(NID_sha3_384) +# define Py_OpenSSL_LN_sha3_384 LN_sha3_384 +# define Py_OpenSSL_NID_sha3_384 NID_sha3_384 +#else +# define Py_OpenSSL_LN_sha3_384 Py_OpenSSL_LN_MISSING +# define Py_OpenSSL_NID_sha3_384 Py_OpenSSL_NID_MISSING +#endif + +// HACL_HID = sha3_512 +#define Py_hmac_sha3_512_block_size 72 +#define Py_hmac_sha3_512_digest_size 64 + +#define Py_hmac_sha3_512_compute_func Hacl_HMAC_compute_sha3_512 + +#if defined(LN_sha3_512) && defined(NID_sha3_512) +# define Py_OpenSSL_LN_sha3_512 LN_sha3_512 +# define Py_OpenSSL_NID_sha3_512 NID_sha3_512 +#else +# define Py_OpenSSL_LN_sha3_512 Py_OpenSSL_LN_MISSING +# define Py_OpenSSL_NID_sha3_512 Py_OpenSSL_NID_MISSING +#endif + +/* Blake2 family */ +// HACL_HID = blake2s_32 +#define Py_hmac_blake2s_32_block_size 64 +#define Py_hmac_blake2s_32_digest_size 32 + +#define Py_hmac_blake2s_32_compute_func Hacl_HMAC_compute_blake2s_32 + +#if defined(LN_blake2s256) && defined(NID_blake2s256) +# define Py_OpenSSL_LN_blake2s_32 LN_blake2s256 +# define Py_OpenSSL_NID_blake2s_32 NID_blake2s256 +#else +# define Py_OpenSSL_LN_blake2s_32 Py_OpenSSL_LN_MISSING +# define Py_OpenSSL_NID_blake2s_32 Py_OpenSSL_NID_MISSING +#endif + +// HACL_HID = blake2b_32 +#define Py_hmac_blake2b_32_block_size 128 +#define Py_hmac_blake2b_32_digest_size 64 + +#define Py_hmac_blake2b_32_compute_func Hacl_HMAC_compute_blake2b_32 + +#if defined(LN_blake2b512) && defined(NID_blake2b512) +# define Py_OpenSSL_LN_blake2b_32 LN_blake2b512 +# define Py_OpenSSL_NID_blake2b_32 NID_blake2b512 +#else +# define Py_OpenSSL_LN_blake2b_32 Py_OpenSSL_LN_MISSING +# define Py_OpenSSL_NID_blake2b_32 Py_OpenSSL_NID_MISSING +#endif + +/* Enumeration indicating the underlying hash function used by HMAC. */ +typedef enum HMAC_Hash_Kind { + Py_hmac_kind_unknown = 0, + /* MD5 */ + Py_hmac_kind_hmac_md5, + /* SHA-1 */ + Py_hmac_kind_hmac_sha1, + /* SHA-2 family */ + Py_hmac_kind_hmac_sha2_224, + Py_hmac_kind_hmac_sha2_256, + Py_hmac_kind_hmac_sha2_384, + Py_hmac_kind_hmac_sha2_512, + /* SHA-3 family */ + Py_hmac_kind_hmac_sha3_224, + Py_hmac_kind_hmac_sha3_256, + Py_hmac_kind_hmac_sha3_384, + Py_hmac_kind_hmac_sha3_512, + /* Blake family */ + Py_hmac_kind_hmac_blake2s_32, + Py_hmac_kind_hmac_blake2b_32, +} HMAC_Hash_Kind; + +/* Function pointer type for 1-shot HACL* HMAC functions. */ +typedef void +(*HACL_HMAC_compute_func)(uint8_t *out, + uint8_t *key, uint32_t keylen, + uint8_t *msg, uint32_t msglen); + +/* Function pointer type for 1-shot HACL* HMAC CPython AC functions. */ +typedef PyObject * +(*PYAC_HMAC_compute_func)(PyObject *module, PyObject *key, PyObject *msg); + +/* + * HACL* HMAC minimal interface. + */ +typedef struct py_hmac_hacl_api { + HACL_HMAC_compute_func compute; + PYAC_HMAC_compute_func compute_py; +} py_hmac_hacl_api; + +/* + * HMAC underlying hash function static information. + * + * The '_hmac' built-in module is able to recognize the same hash + * functions as the '_hashlib' built-in module with the exception + * of truncated SHA-2-512-224/256 which are not yet implemented by + * the HACL* project. + */ +typedef struct py_hmac_hinfo { + /* + * Name of the hash function used by the HACL* HMAC module. + * + * This name may differ from the hashlib names and OpenSSL names. + * For instance, SHA-2/224 is named "sha2_224" instead of "sha224" + * as it is done by 'hashlib'. + */ + const char *name; + /* + * Optional field to cache storing the 'name' field as a Python string. + * + * This field is NULL by default in the items of "py_hmac_hinfo_table" + * but will be populated when creating the module's state "hinfo_table". + */ + PyObject *p_name; + + /* hash function information */ + HMAC_Hash_Kind kind; + uint32_t block_size; + uint32_t digest_size; + + /* HACL* HMAC API */ + py_hmac_hacl_api api; + + const char *hashlib_name; /* hashlib preferred name (default: name) */ + const char *openssl_name; /* OpenSSL EVP preferred name (NULL if none) */ + int openssl_nid; /* OpenSSL EVP NID (-1 if none) */ + + Py_ssize_t refcnt; +} py_hmac_hinfo; + +// --- HMAC module state ------------------------------------------------------ + +typedef struct hmacmodule_state { + _Py_hashtable_t *hinfo_table; + /* imported from _hashlib */ + PyObject *hashlib_constructs_mappingproxy; + PyObject *hashlib_unsupported_digestmod_error; + /* interned strings */ + PyObject *str_lower; +} hmacmodule_state; + +static inline hmacmodule_state * +get_hmacmodule_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (hmacmodule_state *)state; +} + +/*[clinic input] +module _hmac +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=799f0f10157d561f]*/ + +#include "clinic/hmacmodule.c.h" + +// --- Helpers ---------------------------------------------------------------- + +/* Static information used to construct the hash table. */ +static const py_hmac_hinfo py_hmac_static_hinfo[] = { +#define Py_HMAC_HINFO_HACL_API(HACL_HID) \ + { \ + .compute = &Py_hmac_## HACL_HID ##_compute_func, \ + .compute_py = &_hmac_compute_## HACL_HID ##_impl, \ + } + +#define Py_HMAC_HINFO_ENTRY(HACL_HID, HLIB_NAME) \ + { \ + .name = Py_STRINGIFY(HACL_HID), \ + .p_name = NULL, \ + .kind = Py_hmac_kind_hmac_ ## HACL_HID, \ + .block_size = Py_hmac_## HACL_HID ##_block_size, \ + .digest_size = Py_hmac_## HACL_HID ##_digest_size, \ + .api = Py_HMAC_HINFO_HACL_API(HACL_HID), \ + .hashlib_name = HLIB_NAME, \ + .openssl_name = Py_OpenSSL_LN_ ## HACL_HID, \ + .openssl_nid = Py_OpenSSL_NID_ ## HACL_HID, \ + .refcnt = 0, \ + } + /* MD5 */ + Py_HMAC_HINFO_ENTRY(md5, "md5"), + /* SHA-1 */ + Py_HMAC_HINFO_ENTRY(sha1, "sha1"), + /* SHA-2 family */ + Py_HMAC_HINFO_ENTRY(sha2_224, "sha224"), + Py_HMAC_HINFO_ENTRY(sha2_256, "sha256"), + Py_HMAC_HINFO_ENTRY(sha2_384, "sha384"), + Py_HMAC_HINFO_ENTRY(sha2_512, "sha512"), + /* SHA-3 family */ + Py_HMAC_HINFO_ENTRY(sha3_224, NULL), + Py_HMAC_HINFO_ENTRY(sha3_256, NULL), + Py_HMAC_HINFO_ENTRY(sha3_384, NULL), + Py_HMAC_HINFO_ENTRY(sha3_512, NULL), + /* Blake family */ + Py_HMAC_HINFO_ENTRY(blake2s_32, "blake2s256"), + Py_HMAC_HINFO_ENTRY(blake2b_32, "blake2b512"), +#undef Py_HMAC_HINFO_ENTRY +#undef Py_HMAC_HINFO_HACL_API + /* sentinel */ + { + NULL, NULL, Py_hmac_kind_unknown, 0, 0, + {NULL, NULL}, + NULL, Py_OpenSSL_LN_MISSING, Py_OpenSSL_NID_MISSING, + 0, + }, +}; + +static inline bool +find_hash_info_by_utf8name(hmacmodule_state *state, + const char *name, + const py_hmac_hinfo **info) +{ + assert(name != NULL); + *info = _Py_hashtable_get(state->hinfo_table, name); + return *info != NULL; +} + +static bool +find_hash_info_by_evp_nid(hmacmodule_state *state, + int openssl_nid, + const py_hmac_hinfo **info) +{ + assert(openssl_nid != Py_OpenSSL_NID_MISSING); + for (const py_hmac_hinfo *e = py_hmac_static_hinfo; e->name != NULL; e++) { + if (e->openssl_nid == openssl_nid) { + assert(e->openssl_name != Py_OpenSSL_LN_MISSING); + *info = e; + return 1; + } + } + *info = NULL; + return 0; +} + +static bool +find_hash_info_by_evp_name(hmacmodule_state *state, + const char *openssl_name, + const py_hmac_hinfo **info) +{ + assert(openssl_name != NULL); + Py_EVP_MD *digest = Py_EVP_MD_fetch(openssl_name); + if (digest == NULL) { + *info = NULL; + return 0; + } + int nid = EVP_MD_nid(digest); + Py_EVP_MD_free(digest); + return find_hash_info_by_evp_nid(state, nid, info); +} + +static int +find_hash_info_by_name(hmacmodule_state *state, + PyObject *name, + const py_hmac_hinfo **info) +{ + const char *utf8name = PyUnicode_AsUTF8(name); + if (utf8name == NULL) { + goto error; + } + if (find_hash_info_by_utf8name(state, utf8name, info)) { + return 1; + } + + // try to find an alternative using the lowercase name + PyObject *lower = PyObject_CallMethodNoArgs(name, state->str_lower); + if (lower == NULL) { + goto error; + } + const char *utf8lower = PyUnicode_AsUTF8(lower); + if (utf8lower == NULL) { + Py_DECREF(lower); + goto error; + } + int found = find_hash_info_by_utf8name(state, utf8lower, info); + Py_DECREF(lower); + if (found) { + return 1; + } + + // try to resolve via OpenSSL EVP interface as a last resort (slow) + return find_hash_info_by_evp_name(state, utf8name, info); + +error: + *info = NULL; + return -1; +} + +/* + * Find the corresponding HMAC hash function static information. + * + * If an error occurs or if nothing can be found, this + * returns -1 or 0 respectively, and sets 'info' to NULL. + * Otherwise, this returns 1 and stores the result in 'info'. + * + * Parameters + * + * state The HMAC module state. + * hash_info_ref An input to hashlib.new(). + * info The deduced information, if any. + */ +static int +find_hash_info_impl(hmacmodule_state *state, + PyObject *hash_info_ref, + const py_hmac_hinfo **info) +{ + if (PyUnicode_Check(hash_info_ref)) { + return find_hash_info_by_name(state, hash_info_ref, info); + } + PyObject *hashlib_name = NULL; + int rc = PyMapping_GetOptionalItem(state->hashlib_constructs_mappingproxy, + hash_info_ref, &hashlib_name); + if (rc <= 0) { + *info = NULL; + return rc; + } + rc = find_hash_info_by_name(state, hashlib_name, info); + Py_DECREF(hashlib_name); + return rc; +} + +static const py_hmac_hinfo * +find_hash_info(hmacmodule_state *state, PyObject *hash_info_ref) +{ + const py_hmac_hinfo *info = NULL; + int rc = find_hash_info_impl(state, hash_info_ref, &info); + if (rc < 0) { + assert(info == NULL); + assert(PyErr_Occurred()); + return NULL; + } + if (rc == 0) { + assert(info == NULL); + assert(!PyErr_Occurred()); + PyErr_Format(state->hashlib_unsupported_digestmod_error, + "unsupported hash type: %R", hash_info_ref); + return NULL; + } + return info; +} + +/* Check that the buffer length fits on a uint32_t. */ +static inline int +has_uint32_t_buffer_length(const Py_buffer *buffer) +{ +#if PY_SSIZE_T_MAX > UINT32_MAX + return buffer->len <= (Py_ssize_t)UINT32_MAX; +#else + return 1; +#endif +} + +// --- One-shot HMAC-HASH interface ------------------------------------------- + +/*[clinic input] +_hmac.compute_digest + + key: object + msg: object + digestmod: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_digest_impl(PyObject *module, PyObject *key, PyObject *msg, + PyObject *digestmod) +/*[clinic end generated code: output=593ea8a175024c9a input=bd3be7c5b717c950]*/ +{ + hmacmodule_state *state = get_hmacmodule_state(module); + const py_hmac_hinfo *info = find_hash_info(state, digestmod); + if (info == NULL) { + assert(PyErr_Occurred()); + return NULL; + } + assert(info->api.compute_py != NULL); + return info->api.compute_py(module, key, msg); +} + +/* + * One-shot HMAC-HASH using the given HACL_HID. + * + * The length of the key and message buffers must not exceed UINT32_MAX, + * lest an OverflowError is raised. The Python implementation takes care + * of dispatching to the OpenSSL implementation in this case. + */ +#define Py_HMAC_HACL_ONESHOT(HACL_HID, KEY, MSG) \ + do { \ + Py_buffer keyview, msgview; \ + GET_BUFFER_VIEW_OR_ERROUT((KEY), &keyview); \ + if (!has_uint32_t_buffer_length(&keyview)) { \ + PyBuffer_Release(&keyview); \ + PyErr_SetString(PyExc_OverflowError, \ + "key length exceeds UINT32_MAX"); \ + return NULL; \ + } \ + GET_BUFFER_VIEW_OR_ERROUT((MSG), &msgview); \ + if (!has_uint32_t_buffer_length(&msgview)) { \ + PyBuffer_Release(&msgview); \ + PyBuffer_Release(&keyview); \ + PyErr_SetString(PyExc_OverflowError, \ + "message length exceeds UINT32_MAX"); \ + return NULL; \ + } \ + uint8_t out[Py_hmac_## HACL_HID ##_digest_size]; \ + Py_hmac_## HACL_HID ##_compute_func( \ + out, \ + (uint8_t *)keyview.buf, (uint32_t)keyview.len, \ + (uint8_t *)msgview.buf, (uint32_t)msgview.len \ + ); \ + PyBuffer_Release(&msgview); \ + PyBuffer_Release(&keyview); \ + return PyBytes_FromStringAndSize( \ + (const char *)out, \ + Py_hmac_## HACL_HID ##_digest_size \ + ); \ + } while (0) + +/*[clinic input] +_hmac.compute_md5 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_md5_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=7837a4ceccbbf636 input=77a4b774c7d61218]*/ +{ + Py_HMAC_HACL_ONESHOT(md5, key, msg); +} + +/*[clinic input] +_hmac.compute_sha1 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha1_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=79fd7689c83691d8 input=3b64dccc6bdbe4ba]*/ +{ + Py_HMAC_HACL_ONESHOT(sha1, key, msg); +} + +/*[clinic input] +_hmac.compute_sha2_224 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha2_224_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=7f21f1613e53979e input=bcaac7a3637484ce]*/ +{ + Py_HMAC_HACL_ONESHOT(sha2_224, key, msg); +} + +/*[clinic input] +_hmac.compute_sha2_256 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha2_256_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=d4a291f7d9a82459 input=6e2d1f6fe9c56d21]*/ +{ + Py_HMAC_HACL_ONESHOT(sha2_256, key, msg); +} + +/*[clinic input] +_hmac.compute_sha2_384 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha2_384_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=f211fa26e3700c27 input=9ce8de89dda79e62]*/ +{ + Py_HMAC_HACL_ONESHOT(sha2_384, key, msg); +} + +/*[clinic input] +_hmac.compute_sha2_512 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha2_512_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=d5c20373762cecca input=b964bb8487d7debd]*/ +{ + Py_HMAC_HACL_ONESHOT(sha2_512, key, msg); +} + +/*[clinic input] +_hmac.compute_sha3_224 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha3_224_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=a242ccac9ad9c22b input=d0ab0c7d189c3d87]*/ +{ + Py_HMAC_HACL_ONESHOT(sha3_224, key, msg); +} + +/*[clinic input] +_hmac.compute_sha3_256 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha3_256_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=b539dbb61af2fe0b input=f05d7b6364b35d02]*/ +{ + Py_HMAC_HACL_ONESHOT(sha3_256, key, msg); +} + +/*[clinic input] +_hmac.compute_sha3_384 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha3_384_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=5eb372fb5c4ffd3a input=d842d393e7aa05ae]*/ +{ + Py_HMAC_HACL_ONESHOT(sha3_384, key, msg); +} + +/*[clinic input] +_hmac.compute_sha3_512 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_sha3_512_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=154bcbf8c2eacac1 input=166fe5baaeaabfde]*/ +{ + Py_HMAC_HACL_ONESHOT(sha3_512, key, msg); +} + +/*[clinic input] +_hmac.compute_blake2s_32 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_blake2s_32_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=cfc730791bc62361 input=d22c36e7fe31a985]*/ +{ + Py_HMAC_HACL_ONESHOT(blake2s_32, key, msg); +} + +/*[clinic input] +_hmac.compute_blake2b_32 + + key: object + msg: object + / + +[clinic start generated code]*/ + +static PyObject * +_hmac_compute_blake2b_32_impl(PyObject *module, PyObject *key, PyObject *msg) +/*[clinic end generated code: output=765c5c4fb9124636 input=4a35ee058d172f4b]*/ +{ + Py_HMAC_HACL_ONESHOT(blake2b_32, key, msg); +} + +// --- HMAC module methods ---------------------------------------------------- + +static PyMethodDef hmacmodule_methods[] = { + /* one-shot dispatcher */ + _HMAC_COMPUTE_DIGEST_METHODDEF + /* one-shot methods */ + _HMAC_COMPUTE_MD5_METHODDEF + _HMAC_COMPUTE_SHA1_METHODDEF + _HMAC_COMPUTE_SHA2_224_METHODDEF + _HMAC_COMPUTE_SHA2_256_METHODDEF + _HMAC_COMPUTE_SHA2_384_METHODDEF + _HMAC_COMPUTE_SHA2_512_METHODDEF + _HMAC_COMPUTE_SHA3_224_METHODDEF + _HMAC_COMPUTE_SHA3_256_METHODDEF + _HMAC_COMPUTE_SHA3_384_METHODDEF + _HMAC_COMPUTE_SHA3_512_METHODDEF + _HMAC_COMPUTE_BLAKE2S_32_METHODDEF + _HMAC_COMPUTE_BLAKE2B_32_METHODDEF + {NULL, NULL, 0, NULL} +}; + +// --- HMAC static information table ------------------------------------------ + +static inline Py_uhash_t +py_hmac_hinfo_ht_hash(const void *name) +{ + return Py_HashBuffer(name, strlen((const char *)name)); +} + +static inline int +py_hmac_hinfo_ht_comp(const void *a, const void *b) +{ + return strcmp((const char *)a, (const char *)b) == 0; +} + +static void +py_hmac_hinfo_ht_free(void *hinfo) +{ + py_hmac_hinfo *entry = (py_hmac_hinfo *)hinfo; + assert(entry->p_name != NULL); + if (--(entry->refcnt) == 0) { + Py_CLEAR(entry->p_name); + PyMem_Free(hinfo); + } +} + +static inline int +py_hmac_hinfo_ht_add(_Py_hashtable_t *table, const void *key, void *info) +{ + if (key == NULL || _Py_hashtable_get(table, key) != NULL) { + return 0; + } + int ok = _Py_hashtable_set(table, key, info); + return ok < 0 ? -1 : ok == 0; +} + +static _Py_hashtable_t * +py_hmac_hinfo_ht_new(void) +{ + _Py_hashtable_t *table = _Py_hashtable_new_full( + py_hmac_hinfo_ht_hash, + py_hmac_hinfo_ht_comp, + NULL, + py_hmac_hinfo_ht_free, + NULL + ); + + if (table == NULL) { + return NULL; + } + + for (const py_hmac_hinfo *e = py_hmac_static_hinfo; e->name != NULL; e++) { + py_hmac_hinfo *value = PyMem_Malloc(sizeof(py_hmac_hinfo)); + if (value == NULL) { + goto error; + } + + memcpy(value, e, sizeof(py_hmac_hinfo)); + assert(value->p_name == NULL); + value->refcnt = 0; + +#define Py_HMAC_HINFO_LINK(KEY) \ + do { \ + int rc = py_hmac_hinfo_ht_add(table, KEY, value); \ + if (rc < 0) { \ + PyMem_Free(value); \ + goto error; \ + } \ + else if (rc == 1) { \ + value->refcnt++; \ + } \ + } while (0) + Py_HMAC_HINFO_LINK(e->name); + Py_HMAC_HINFO_LINK(e->hashlib_name); + Py_HMAC_HINFO_LINK(e->openssl_name); +#undef Py_HMAC_HINFO_LINK + assert(value->refcnt > 0); + value->p_name = PyUnicode_FromString(e->name); + if (value->p_name == NULL) { + PyMem_Free(value); + goto error; + } + } + + return table; + +error: + _Py_hashtable_destroy(table); + return NULL; +} + +// --- HMAC module initialization and finalization functions ------------------ + +static int +hmacmodule_init_hash_info_table(hmacmodule_state *state) +{ + state->hinfo_table = py_hmac_hinfo_ht_new(); + if (state->hinfo_table == NULL) { + // An exception other than a memory error can be raised + // by PyUnicode_FromString() or _Py_hashtable_set() when + // creating the hash table entries. + if (!PyErr_Occurred()) { + PyErr_NoMemory(); + } + return -1; + } + return 0; +} + +static int +hmacmodule_init_from_hashlib(hmacmodule_state *state) +{ + PyObject *_hashlib = PyImport_ImportModule("_hashlib"); + if (_hashlib == NULL) { + return -1; + } +#define IMPORT_FROM_HASHLIB(VAR, NAME) \ + do { \ + (VAR) = PyObject_GetAttrString(_hashlib, NAME); \ + if ((VAR) == NULL) { \ + Py_DECREF(_hashlib); \ + return -1; \ + } \ + } while (0) + + IMPORT_FROM_HASHLIB(state->hashlib_constructs_mappingproxy, + "_constructors"); + IMPORT_FROM_HASHLIB(state->hashlib_unsupported_digestmod_error, + "UnsupportedDigestmodError"); +#undef IMPORT_FROM_HASHLIB + Py_DECREF(_hashlib); + return 0; +} + +static int +hmacmodule_init_strings(hmacmodule_state *state) +{ + state->str_lower = PyUnicode_FromString("lower"); + if (state->str_lower == NULL) { + return -1; + } + return 0; +} + +static int +hmacmodule_exec(PyObject *module) +{ + hmacmodule_state *state = get_hmacmodule_state(module); + if (hmacmodule_init_hash_info_table(state) < 0) { + return -1; + } + if (hmacmodule_init_from_hashlib(state) < 0) { + return -1; + } + if (hmacmodule_init_strings(state) < 0) { + return -1; + } + return 0; +} + +static int +hmacmodule_traverse(PyObject *mod, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(mod)); + hmacmodule_state *state = get_hmacmodule_state(mod); + Py_VISIT(state->hashlib_constructs_mappingproxy); + Py_VISIT(state->hashlib_unsupported_digestmod_error); + Py_VISIT(state->str_lower); + return 0; +} + +static int +hmacmodule_clear(PyObject *mod) +{ + hmacmodule_state *state = get_hmacmodule_state(mod); + if (state->hinfo_table != NULL) { + _Py_hashtable_destroy(state->hinfo_table); + state->hinfo_table = NULL; + } + Py_CLEAR(state->hashlib_constructs_mappingproxy); + Py_CLEAR(state->hashlib_unsupported_digestmod_error); + Py_CLEAR(state->str_lower); + return 0; +} + +static inline void +hmacmodule_free(void *mod) +{ + (void)hmacmodule_clear((PyObject *)mod); +} + +static struct PyModuleDef_Slot hmacmodule_slots[] = { + {Py_mod_exec, hmacmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0, NULL} +}; + +static struct PyModuleDef _hmacmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_hmac", + .m_size = sizeof(hmacmodule_state), + .m_methods = hmacmodule_methods, + .m_slots = hmacmodule_slots, + .m_traverse = hmacmodule_traverse, + .m_clear = hmacmodule_clear, + .m_free = hmacmodule_free, +}; + +PyMODINIT_FUNC +PyInit__hmac(void) +{ + return PyModuleDef_Init(&_hmacmodule); +} diff --git a/PC/config.c b/PC/config.c index b744f711b0d636..1af3d1ecbd2851 100644 --- a/PC/config.c +++ b/PC/config.c @@ -25,6 +25,7 @@ extern PyObject* PyInit__statistics(void); extern PyObject* PyInit__sysconfig(void); extern PyObject* PyInit__typing(void); extern PyObject* PyInit__blake2(void); +extern PyObject* PyInit__hmac(void); extern PyObject* PyInit_time(void); extern PyObject* PyInit__thread(void); #ifdef WIN32 @@ -102,6 +103,7 @@ struct _inittab _PyImport_Inittab[] = { {"_sha2", PyInit__sha2}, {"_sha3", PyInit__sha3}, {"_blake2", PyInit__blake2}, + {"_hmac", PyInit__hmac}, {"_sysconfig", PyInit__sysconfig}, {"time", PyInit_time}, {"_thread", PyInit__thread}, diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 95552cade52b75..77716d42c56893 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -435,6 +435,7 @@ + @@ -471,6 +472,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 1708cf6e0b3a52..c873ed72af5c59 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -944,6 +944,9 @@ Modules + + Modules + Modules @@ -998,6 +1001,9 @@ Modules + + Modules + Modules @@ -1013,6 +1019,9 @@ Modules + + Modules + Modules diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index c8cdb933bb108f..46a7c744750cac 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -38,6 +38,7 @@ static const char* _Py_stdlib_module_names[] = { "_gdbm", "_hashlib", "_heapq", +"_hmac", "_imp", "_interpchannels", "_interpqueues", diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index 21be53e78841d5..5567ae091e2ef8 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -128,6 +128,7 @@ def clean_lines(text): Modules/sha2module.c Modules/_hacl/include Modules/sha3module.c Modules/_hacl/include Modules/blake2module.c Modules/_hacl/include +Modules/hmacmodule.c Modules/_hacl/include Objects/stringlib/*.h Objects # possible system-installed headers, just in case diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 686f3935d91bda..4d8f5183e78ae5 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -302,6 +302,7 @@ Modules/cmathmodule.c - sqrt_special_values - Modules/cmathmodule.c - tanh_special_values - Modules/config.c - _PyImport_Inittab - Modules/faulthandler.c - faulthandler_handlers - +Modules/hmacmodule.c - py_hmac_static_hinfo - Modules/getnameinfo.c - gni_afdl - Modules/posixmodule.c os_getxattr_impl buffer_sizes - Modules/posixmodule.c os_listxattr_impl buffer_sizes - diff --git a/configure b/configure index b1ced3106618ba..74f9598b7080de 100755 --- a/configure +++ b/configure @@ -681,6 +681,8 @@ MODULE__TESTCLINIC_FALSE MODULE__TESTCLINIC_TRUE MODULE__TESTCAPI_FALSE MODULE__TESTCAPI_TRUE +MODULE__HMAC_FALSE +MODULE__HMAC_TRUE MODULE__HASHLIB_FALSE MODULE__HASHLIB_TRUE MODULE__SSL_FALSE @@ -28951,6 +28953,67 @@ LIBS=$save_LIBS +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS $LIBCRYPTO_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required hmac module APIs" >&5 +printf %s "checking whether OpenSSL provides required hmac module APIs... " >&6; } +if test ${ac_cv_working_openssl_hmac+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + +int +main (void) +{ + + OBJ_nid2sn(NID_md5); + OBJ_nid2sn(NID_sha1); + OBJ_nid2sn(NID_sha224); + OBJ_nid2sn(NID_sha256); + OBJ_nid2sn(NID_sha384); + OBJ_nid2sn(NID_sha512); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_working_openssl_hmac=yes +else $as_nop + ac_cv_working_openssl_hmac=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_hmac" >&5 +printf "%s\n" "$ac_cv_working_openssl_hmac" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + # ssl module default cipher suite string @@ -31469,6 +31532,44 @@ fi printf "%s\n" "$py_cv_module__hashlib" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hmac" >&5 +printf %s "checking for stdlib extension module _hmac... " >&6; } + if test "$py_cv_module__hmac" != "n/a" +then : + + if true +then : + if test "$ac_cv_working_openssl_hmac" = yes +then : + py_cv_module__hmac=yes +else $as_nop + py_cv_module__hmac=missing +fi +else $as_nop + py_cv_module__hmac=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__HMAC_STATE=$py_cv_module__hmac$as_nl" + if test "x$py_cv_module__hmac" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__HMAC_CFLAGS=$LIBHACL_CFLAGS $OPENSSL_INCLUDES$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HMAC_LDFLAGS=$LIBHACL_CFLAGS Modules/_hacl/libHacl_HMAC.a $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS$as_nl" + +fi + if test "$py_cv_module__hmac" = yes; then + MODULE__HMAC_TRUE= + MODULE__HMAC_FALSE='#' +else + MODULE__HMAC_TRUE='#' + MODULE__HMAC_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hmac" >&5 +printf "%s\n" "$py_cv_module__hmac" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5 printf %s "checking for stdlib extension module _testcapi... " >&6; } @@ -32430,6 +32531,10 @@ if test -z "${MODULE__HASHLIB_TRUE}" && test -z "${MODULE__HASHLIB_FALSE}"; then as_fn_error $? "conditional \"MODULE__HASHLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__HMAC_TRUE}" && test -z "${MODULE__HMAC_FALSE}"; then + as_fn_error $? "conditional \"MODULE__HMAC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__TESTCAPI_TRUE}" && test -z "${MODULE__TESTCAPI_FALSE}"; then as_fn_error $? "conditional \"MODULE__TESTCAPI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/configure.ac b/configure.ac index 3a55cbc1320393..8ce28ec585cd58 100644 --- a/configure.ac +++ b/configure.ac @@ -7384,6 +7384,29 @@ WITH_SAVE_ENV([ ]) ]) +WITH_SAVE_ENV([ + LIBS="$LIBS $LIBCRYPTO_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + AC_CACHE_CHECK([whether OpenSSL provides required hmac module APIs], [ac_cv_working_openssl_hmac], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + ], [ + OBJ_nid2sn(NID_md5); + OBJ_nid2sn(NID_sha1); + OBJ_nid2sn(NID_sha224); + OBJ_nid2sn(NID_sha256); + OBJ_nid2sn(NID_sha384); + OBJ_nid2sn(NID_sha512); + ])], [ac_cv_working_openssl_hmac=yes], [ac_cv_working_openssl_hmac=no]) + ]) +]) + # ssl module default cipher suite string AH_TEMPLATE([PY_SSL_DEFAULT_CIPHERS], [Default cipher suites list for ssl module. @@ -7913,6 +7936,9 @@ PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes], [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS]) PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) +PY_STDLIB_MOD([_hmac], [], [test "$ac_cv_working_openssl_hmac" = yes], + [$LIBHACL_CFLAGS $OPENSSL_INCLUDES], + [$LIBHACL_CFLAGS Modules/_hacl/libHacl_HMAC.a $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) dnl test modules PY_STDLIB_MOD([_testcapi],