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..0a1d1439b0aa3a --- /dev/null +++ b/Modules/hmacmodule.c @@ -0,0 +1,972 @@ +#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 + +// --- Reusable error messages ------------------------------------------------ + +#define INVALID_KEY_LENGTH "key length exceeds UINT32_MAX" +#define INVALID_MSG_LENGTH "message length exceeds UINT32_MAX" + +// --- 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, INVALID_KEY_LENGTH); \ + return NULL; \ + } \ + GET_BUFFER_VIEW_OR_ERROR((MSG), &msgview, \ + PyBuffer_Release(&keyview); \ + return NULL); \ + if (!has_uint32_t_buffer_length(&msgview)) { \ + PyBuffer_Release(&msgview); \ + PyBuffer_Release(&keyview); \ + PyErr_SetString(PyExc_OverflowError, INVALID_MSG_LENGTH); \ + 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], pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy