diff --git a/CMakeLists.txt b/CMakeLists.txt index 283953e6..036dde8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,38 +247,47 @@ ADD_CUSTOM_COMMAND( ### Native library configuration include_directories(${OPENSSL_INCLUDE_DIR} ${JNI_INCLUDE_DIRS} ${JNI_HEADER_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp) -add_library( - amazonCorrettoCryptoProvider SHARED - csrc/aes_gcm.cpp - csrc/aes_xts.cpp - csrc/aes_cbc.cpp - csrc/aes_kwp.cpp - csrc/agreement.cpp - csrc/bn.cpp - csrc/buffer.cpp - csrc/ec_gen.cpp - csrc/ec_utils.cpp - csrc/env.cpp - csrc/hkdf.cpp - csrc/hmac.cpp - csrc/keyutils.cpp - csrc/java_evp_keys.cpp - csrc/libcrypto_rng.cpp - csrc/loader.cpp - csrc/md5.cpp - csrc/rsa_cipher.cpp - csrc/rsa_gen.cpp - csrc/sha1.cpp - csrc/sha256.cpp - csrc/sha384.cpp - csrc/sha512.cpp - csrc/sign.cpp - csrc/testhooks.cpp - csrc/util.cpp - csrc/util_class.cpp - csrc/fips_kat_self_test.cpp - ${JNI_HEADER_DIR}/generated-headers.h -) +set(C_SRC + csrc/aes_gcm.cpp + csrc/aes_xts.cpp + csrc/aes_cbc.cpp + csrc/aes_kwp.cpp + csrc/agreement.cpp + csrc/bn.cpp + csrc/buffer.cpp + csrc/ec_gen.cpp + csrc/ec_utils.cpp + csrc/env.cpp + csrc/hkdf.cpp + csrc/hmac.cpp + csrc/keyutils.cpp + csrc/java_evp_keys.cpp + csrc/libcrypto_rng.cpp + csrc/loader.cpp + csrc/md5.cpp + csrc/rsa_cipher.cpp + csrc/rsa_gen.cpp + csrc/sha1.cpp + csrc/sha256.cpp + csrc/sha384.cpp + csrc/sha512.cpp + csrc/sign.cpp + csrc/testhooks.cpp + csrc/util.cpp + csrc/util_class.cpp + csrc/fips_kat_self_test.cpp + ${JNI_HEADER_DIR}/generated-headers.h) + +if(FIPS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFIPS_BUILD") + set(TEST_FIPS_PROPERTY "-DFIPS=true") +else() + set(TEST_FIPS_PROPERTY "-DFIPS=false") + set(C_SRC ${C_SRC} + csrc/concatenation_kdf.cpp) +endif() + +add_library(amazonCorrettoCryptoProvider SHARED ${C_SRC}) add_custom_command( OUTPUT ${ACCP_JAR_SOURCE} @@ -616,12 +625,6 @@ set(COVERAGE_ARGUMENTS -javaagent:${JACOCO_AGENT_JAR}=destfile=coverage/jacoco.exec,classdumpdir=coverage/classes ) -if(FIPS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFIPS_BUILD") - set(TEST_FIPS_PROPERTY "-DFIPS=true") -else() - set(TEST_FIPS_PROPERTY "-DFIPS=false") -endif() if(ALWAYS_ALLOW_EXTERNAL_LIB) set(EXTERNAL_LIB_PROPERTY "-Djava.library.path=$") diff --git a/README.md b/README.md index cd9ce154..6929da94 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,11 @@ SecretKeyFactory: * HkdfWithHmacSHA256 * HkdfWithHmacSHA384 * HkdfWithHmacSHA512 +* ConcatenationKdfWithSHA256 (not available in FIPS builds) +* ConcatenationKdfWithSHA384 (not available in FIPS builds) +* ConcatenationKdfWithSHA512 (not available in FIPS builds) +* ConcatenationKdfWithHmacSHA256 (not available in FIPS builds) +* ConcatenationKdfWithHmacSHA512 (not available in FIPS builds) SecureRandom: * ACCP's SecureRandom uses [AWS-LC's DRBG implementation](https://github.com/aws/aws-lc/blob/main/crypto/fipsmodule/rand/rand.c). diff --git a/aws-lc b/aws-lc index 4368aaa6..05747780 160000 --- a/aws-lc +++ b/aws-lc @@ -1 +1 @@ -Subproject commit 4368aaa6975ba41bd76d3bb12fac54c4680247fb +Subproject commit 05747780676652f41d0b9c570a495e4bb6608560 diff --git a/build.gradle b/build.gradle index 8a49bad6..b4885c51 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ ext.isFips = Boolean.getBoolean('FIPS') if (ext.isFips) { ext.awsLcGitVersionId = 'AWS-LC-FIPS-2.0.13' } else { - ext.awsLcGitVersionId = 'v1.30.1' + ext.awsLcGitVersionId = 'v1.33.0' } // Check for user inputted git version ID. diff --git a/csrc/concatenation_kdf.cpp b/csrc/concatenation_kdf.cpp new file mode 100644 index 00000000..1c0a32c4 --- /dev/null +++ b/csrc/concatenation_kdf.cpp @@ -0,0 +1,61 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +#include "buffer.h" +#include "env.h" +#include "generated-headers.h" +#include +#include + +using namespace AmazonCorrettoCryptoProvider; + +extern "C" JNIEXPORT void Java_com_amazon_corretto_crypto_provider_ConcatenationKdfSpi_nSskdfDigest(JNIEnv* env, + jclass, + jint digestCode, + jbyteArray jSecret, + jint secretLen, + jbyteArray jInfo, + jint infoLen, + jbyteArray jOutput, + jint outputLen) +{ + try { + EVP_MD const* digest = digest_code_to_EVP_MD(digestCode); + JBinaryBlob secret(env, nullptr, jSecret); + JBinaryBlob info(env, nullptr, jInfo); + JBinaryBlob output(env, nullptr, jOutput); + if (SSKDF_digest(output.get(), outputLen, digest, secret.get(), secretLen, info.get(), infoLen) != 1) { + throw_openssl(EX_RUNTIME_CRYPTO, "SSKDF_digest failed."); + } + } catch (java_ex& ex) { + ex.throw_to_java(env); + } +} + +extern "C" JNIEXPORT void JNICALL Java_com_amazon_corretto_crypto_provider_ConcatenationKdfSpi_nSskdfHmac(JNIEnv* env, + jclass, + jint digestCode, + jbyteArray jSecret, + jint secretLen, + jbyteArray jInfo, + jint infoLen, + jbyteArray jSalt, + jint saltLen, + jbyteArray jOutput, + jint outputLen) +{ + try { + EVP_MD const* digest = digest_code_to_EVP_MD(digestCode); + JBinaryBlob secret(env, nullptr, jSecret); + JBinaryBlob info(env, nullptr, jInfo); + JBinaryBlob salt(env, nullptr, jSalt); + JBinaryBlob output(env, nullptr, jOutput); + if (SSKDF_hmac( + output.get(), outputLen, digest, secret.get(), secretLen, info.get(), infoLen, salt.get(), saltLen) + != 1) { + throw_openssl(EX_RUNTIME_CRYPTO, "SSKDF_hmac failed."); + } + + } catch (java_ex& ex) { + ex.throw_to_java(env); + } +} diff --git a/csrc/keyutils.cpp b/csrc/keyutils.cpp index c1a0d244..0ac1e7e5 100644 --- a/csrc/keyutils.cpp +++ b/csrc/keyutils.cpp @@ -189,7 +189,7 @@ RSA* new_private_RSA_key_with_no_e(BIGNUM const* n, BIGNUM const* d) #else - RSA* result = RSA_new_private_key_no_e(n, d); + RSA* result = ::RSA_new_private_key_no_e(n, d); if (result == nullptr) { throw_openssl("RSA_new_private_key_no_e failed."); diff --git a/src/com/amazon/corretto/crypto/provider/AmazonCorrettoCryptoProvider.java b/src/com/amazon/corretto/crypto/provider/AmazonCorrettoCryptoProvider.java index eb646098..060bc929 100644 --- a/src/com/amazon/corretto/crypto/provider/AmazonCorrettoCryptoProvider.java +++ b/src/com/amazon/corretto/crypto/provider/AmazonCorrettoCryptoProvider.java @@ -5,6 +5,11 @@ import static com.amazon.corretto.crypto.provider.AesCbcSpi.AES_CBC_ISO10126_PADDING_NAMES; import static com.amazon.corretto.crypto.provider.AesCbcSpi.AES_CBC_NO_PADDING_NAMES; import static com.amazon.corretto.crypto.provider.AesCbcSpi.AES_CBC_PKCS7_PADDING_NAMES; +import static com.amazon.corretto.crypto.provider.ConcatenationKdfSpi.CKDF_WITH_HMAC_SHA256; +import static com.amazon.corretto.crypto.provider.ConcatenationKdfSpi.CKDF_WITH_HMAC_SHA512; +import static com.amazon.corretto.crypto.provider.ConcatenationKdfSpi.CKDF_WITH_SHA256; +import static com.amazon.corretto.crypto.provider.ConcatenationKdfSpi.CKDF_WITH_SHA384; +import static com.amazon.corretto.crypto.provider.ConcatenationKdfSpi.CKDF_WITH_SHA512; import static com.amazon.corretto.crypto.provider.HkdfSecretKeyFactorySpi.HKDF_WITH_SHA1; import static com.amazon.corretto.crypto.provider.HkdfSecretKeyFactorySpi.HKDF_WITH_SHA256; import static com.amazon.corretto.crypto.provider.HkdfSecretKeyFactorySpi.HKDF_WITH_SHA384; @@ -87,6 +92,16 @@ private void buildServiceMap() { addService("SecretKeyFactory", HKDF_WITH_SHA384, hkdfSpi, false); addService("SecretKeyFactory", HKDF_WITH_SHA512, hkdfSpi, false); + // Once these KDFs are added to a FIPS branch of AWS-LC, we can remove this check. + if (!Loader.FIPS_BUILD) { + final String concatenationKdfSpi = "ConcatenationKdf"; + addService("SecretKeyFactory", CKDF_WITH_SHA256, concatenationKdfSpi, false); + addService("SecretKeyFactory", CKDF_WITH_SHA384, concatenationKdfSpi, false); + addService("SecretKeyFactory", CKDF_WITH_SHA512, concatenationKdfSpi, false); + addService("SecretKeyFactory", CKDF_WITH_HMAC_SHA256, concatenationKdfSpi, false); + addService("SecretKeyFactory", CKDF_WITH_HMAC_SHA512, concatenationKdfSpi, false); + } + addService("KeyPairGenerator", "RSA", "RsaGen"); addService("KeyPairGenerator", "EC", "EcGen"); @@ -309,6 +324,12 @@ public Object newInstance(final Object constructorParameter) throws NoSuchAlgori if (spi != null) { return spi; } + + final ConcatenationKdfSpi ckdfSpi = + ConcatenationKdfSpi.INSTANCES.get(ConcatenationKdfSpi.getSpiFactoryForAlgName(algo)); + if (ckdfSpi != null) { + return ckdfSpi; + } } if ("KeyGenerator".equalsIgnoreCase(type) && "AES".equalsIgnoreCase(algo)) { diff --git a/src/com/amazon/corretto/crypto/provider/ConcatenationKdfSpec.java b/src/com/amazon/corretto/crypto/provider/ConcatenationKdfSpec.java new file mode 100644 index 00000000..7ff47d97 --- /dev/null +++ b/src/com/amazon/corretto/crypto/provider/ConcatenationKdfSpec.java @@ -0,0 +1,70 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.corretto.crypto.provider; + +import java.security.spec.KeySpec; +import java.util.Objects; + +/** + * Represents the inputs to ConcatenationKdf algorithms. + * + *

If info or salt is not provided, empty byte arrays are used. + * + *

The algorithmName is the name of algorithm used to create SecretKeySpec. + */ +public class ConcatenationKdfSpec implements KeySpec { + private final byte[] secret; + private final int outputLen; + private final String algorithmName; + private final byte[] info; + private final byte[] salt; + + public ConcatenationKdfSpec( + final byte[] secret, + final int outputLen, + final String algorithmName, + final byte[] info, + final byte[] salt) { + this.secret = Objects.requireNonNull(secret); + if (this.secret.length == 0) { + throw new IllegalArgumentException("Secret must be byte array with non-zero length."); + } + if (outputLen <= 0) { + throw new IllegalArgumentException("Output size must be greater than zero."); + } + this.outputLen = outputLen; + this.algorithmName = Objects.requireNonNull(algorithmName); + this.info = Objects.requireNonNull(info); + this.salt = Objects.requireNonNull(salt); + } + + public ConcatenationKdfSpec( + final byte[] secret, final int outputLen, final String algorithmName) { + this(secret, outputLen, algorithmName, Utils.EMPTY_ARRAY, Utils.EMPTY_ARRAY); + } + + public ConcatenationKdfSpec( + final byte[] secret, final int outputLen, final String algorithmName, final byte[] info) { + this(secret, outputLen, algorithmName, info, Utils.EMPTY_ARRAY); + } + + public byte[] getSecret() { + return secret; + } + + public byte[] getInfo() { + return info; + } + + public int getOutputLen() { + return outputLen; + } + + public byte[] getSalt() { + return salt; + } + + public String getAlgorithmName() { + return algorithmName; + } +} diff --git a/src/com/amazon/corretto/crypto/provider/ConcatenationKdfSpi.java b/src/com/amazon/corretto/crypto/provider/ConcatenationKdfSpi.java new file mode 100644 index 00000000..e720cff3 --- /dev/null +++ b/src/com/amazon/corretto/crypto/provider/ConcatenationKdfSpi.java @@ -0,0 +1,112 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.corretto.crypto.provider; + +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +class ConcatenationKdfSpi extends KdfSpi { + private final int digestCode; + // Determines if the digest algorithm should be used as backing PRF or the HMAC. + private final boolean digestAsPrf; + + ConcatenationKdfSpi(final int digestCode, final boolean digestAsPrf) { + this.digestCode = digestCode; + this.digestAsPrf = digestAsPrf; + } + + @Override + protected SecretKey engineGenerateSecret(final KeySpec keySpec) throws InvalidKeySpecException { + if (!(keySpec instanceof ConcatenationKdfSpec)) { + throw new InvalidKeySpecException("Expected a key spec of type ConcatenationKdfSpi."); + } + final ConcatenationKdfSpec spec = (ConcatenationKdfSpec) keySpec; + + final byte[] output = new byte[spec.getOutputLen()]; + + if (digestAsPrf) { + nSskdfDigest( + digestCode, + spec.getSecret(), + spec.getSecret().length, + spec.getInfo(), + spec.getInfo().length, + output, + output.length); + } else { + nSskdfHmac( + digestCode, + spec.getSecret(), + spec.getSecret().length, + spec.getInfo(), + spec.getInfo().length, + spec.getSalt(), + spec.getSalt().length, + output, + output.length); + } + + return new SecretKeySpec(output, spec.getAlgorithmName()); + } + + private static native void nSskdfDigest( + int digestCode, + byte[] secret, + int secretLen, + byte[] info, + int infoLen, + byte[] output, + int outputLen); + + private static native void nSskdfHmac( + int digestCode, + byte[] secret, + int secretLen, + byte[] info, + int infoLen, + byte[] salt, + int saltLen, + byte[] output, + int outputLen); + + static final Map INSTANCES = getInstances(); + + private static final String CKDF = "ConcatenationKdf"; + private static final String WITH = "With"; + static final String CKDF_WITH_SHA256 = CKDF + WITH + "SHA256"; + static final String CKDF_WITH_SHA384 = CKDF + WITH + "SHA384"; + static final String CKDF_WITH_SHA512 = CKDF + WITH + "SHA512"; + static final String CKDF_WITH_HMAC_SHA256 = CKDF + WITH + "HmacSHA256"; + static final String CKDF_WITH_HMAC_SHA512 = CKDF + WITH + "HmacSHA512"; + + private static Map getInstances() { + final Map kdfs = new HashMap<>(); + kdfs.put( + getSpiFactoryForAlgName(CKDF_WITH_SHA256), + new ConcatenationKdfSpi(Utils.SHA256_CODE, true)); + kdfs.put( + getSpiFactoryForAlgName(CKDF_WITH_SHA384), + new ConcatenationKdfSpi(Utils.SHA384_CODE, true)); + kdfs.put( + getSpiFactoryForAlgName(CKDF_WITH_SHA512), + new ConcatenationKdfSpi(Utils.SHA512_CODE, true)); + + kdfs.put( + getSpiFactoryForAlgName(CKDF_WITH_HMAC_SHA256), + new ConcatenationKdfSpi(Utils.SHA256_CODE, false)); + kdfs.put( + getSpiFactoryForAlgName(CKDF_WITH_HMAC_SHA512), + new ConcatenationKdfSpi(Utils.SHA512_CODE, false)); + + return Collections.unmodifiableMap(kdfs); + } + + static String getSpiFactoryForAlgName(final String alg) { + return alg.toUpperCase(); + } +} diff --git a/test-data/sskdf.txt b/test-data/sskdf.txt new file mode 100644 index 00000000..75e27cce --- /dev/null +++ b/test-data/sskdf.txt @@ -0,0 +1,1209 @@ +[TESTS] + +HASH=SHA1 +VARIANT=DIGEST +SECRET=81f3d2ad1f70fd67a374547d59506a04d545f4e869f00fa0 +INFO=434156536964e63969525e54d806789d7121a1b2c3d4e581597a0e979d5c99a79b1789b41ae57fef5b916f85a1e449 +EXPECT=6ff62398511a8a243513 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=1b36653c8d00d4742982e7347e3591b04a6507ffff2d60cf +INFO=4341565369647ebfbe28a821381fd4acacbda1b2c3d4e59f086148af5b212020587c5bca84b1cc856ee790473f6f43 +EXPECT=190109cefea280e8413d + +HASH=SHA1 +VARIANT=DIGEST +SECRET=805ed191d06b9e65bb866babe3d81dfdaf50170a57b6fd72 +INFO=43415653696432a993134a35b0bb99b23c50a1b2c3d4e53948d820d0da600eb36a3d0b4074508306d74879cccec51b +EXPECT=5bade971de631bc7d912 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=d3cd77a44a1e951b23b698b04c3f342780b00917c9c2c2fb +INFO=434156536964600097e08aedd076438dcb2fa1b2c3d4e52880245fa69c4ea8b9dc5e4d8f4984c98855c1303aca04c1 +EXPECT=f53465669cf0a327c2e3 + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=a4801c1ca39cc74b7df5c127593e3482f4c4e4e945753076 +INFO=4341565369649a34a5c3879740e3907add7ba1b2c3d4e5658aaff1cc4bd0aa8e7a215ad1f61873ce67cd7b83225010 +EXPECT=13229b870d7e49795f34 + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=008392d899edd742510212be86e6ba5eede4f354b034b2f4df0e6f5a0003f3b334aebbd3 +INFO=434156536964808e2f1e4b8a68301e33483b423d0a9b6d15a1b2c3d4e5f3c9e8598a950b971c402d0d65a290845fde +EXPECT=2041f42703fd9ff370373fef399009cd + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=0189e7c2133207b3f37741fd596d532bfd37a62b2f6577678f42e0643300a3f20c1f4bed +INFO=434156536964cc2ac48877251aef42fd21686b0aa425a838a1b2c3d4e5da4e1b22f244bdf689861da265954b433e14 +EXPECT=247b5fb8977bf202b9c6fc81e07c7deb + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=07ce5c270ad7d39b0d4c594eb66620fbfc424ee8464c6c12cff08307d34f74082b7a9f54 +INFO=434156536964bd813bb05390d7bbd94ff0b3687c157ca53da1b2c3d4e5a42c7a0c533d316edcd318fbac3a9f754f5e +EXPECT=fab546ee7a66c58e0a0501ce63e0731f + +HASH=SHA-384 +VARIANT=DIGEST +SECRET=016995ef4b250d677dc674577427a0603b5d2185ee66e88c2f450c47727cfafa5707c5b74f9d6a2403f571094eaa7ee54bb251de +INFO=434156536964ac9a3236f3d2a4cda1ada36079b3275556220286c036169ebda8a1b2c3d4e575408962a5a3c8afeb92 +EXPECT=86a4a396d8819edfab9784f668b997fe9a1da99f6f08c5b1 + +HASH=SHA-384 +VARIANT=DIGEST +SECRET=00c12d6863ff167766e1ee061eb53109f281d5ffb0593939fb37281354110cffa0f73f2f3761524f86d047e57f8e3fa04f7ba9ea +INFO=43415653696495b4b25586d6a8a0653ea547ce23d757ee125ff89f889e9cd4c0a1b2c3d4e50ebd18fdde3f0429c876 +EXPECT=3ca777a800ff751ecfc610b08ce3506aab4541cba38b1cb8 + +HASH=SHA-384 +VARIANT=DIGEST +SECRET=012060eb88ab29fa77688ab0ea23fcd21af79456598b82f5212e7e0b835fecca08c6a6fd5d49a264cc6d66f93bf8a436c1fadd60 +INFO=43415653696433a0c05720cd9ae757b38a71e9abd634e90fbd842bf15b1d4c0da1b2c3d4e54e7d6c1bc80533e7452d +EXPECT=241e45e9cbe075abe0a0aed94834d97f704d4a62da1889ec + +HASH=SHA-384 +VARIANT=DIGEST +SECRET=01b11eb41c758b28cb326d78e33ffcacd5ace2ab395281f791fd4f7a80649fd47d4d091bb9cc1c725a4c32715165291b5f522a1a +INFO=4341565369647cdaff4407f99eae33795b0aaf968c20b0071dfe9fe0e3f80eb7a1b2c3d4e5457a0daef12445a665f0 +EXPECT=c0f969c63e99d1798f0a52907b6e42c952611940618733c1 + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=017812834e28c2930b612b15de106b241948a823291480cfe2c7515530aff60cd8eee86f6100769a889bbfda985d6fb60e12104c +INFO=4341565369644e1d7bb30359f9dfcf4a622e809a87bf0c78ac5775eb8b54ef66a1b2c3d4e54f288cc26c3a5c84d344 +EXPECT=61b86d9bf5783c89e9a30b4e30d2c0096544c74d1677820f + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=0184c49404209f6c0af846444fb5705da3875c8a84b6f43004e9e6fae6d2faaaef26d0853fe191624b74de855955807077cd1e6a +INFO=43415653696426abad2b9558fc7450a4e2a9416330626c17ad5a7667ba7e64cca1b2c3d4e5b49c2962094b5387f0d1 +EXPECT=76ee4f052b5862138b91de6b57b9f9ab74f8263ef72948eb + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=016774c65fb07b9d3d737d027ae5409999b1a3965c8f9d4b470c50be201e75f9ee6cc6cfe3863d0e683971b92512cfb64b816e24 +INFO=434156536964fa87a7dda67d13f0aded76ef7a62bf5b9ffa25e024691a7e1f40a1b2c3d4e5902e4f6e3f344a95c3f8 +EXPECT=51cad9a349609ad538704ab813d82401a23f2c1c7d429912 + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=0058d0c565a00f423efb4ccc321acddf7b2e24ba9e259c5ac43845e97b1117a8b89a30b02f9421e31c60ebeac22c6b42b95d4a56 +INFO=434156536964f5c1165e63acf905b51ac0bcaf116b51737b49a3f6cb1063b1e3a1b2c3d4e5e150d4c3b125bf032b47 +EXPECT=7abf9a0654a90c18b0d423bb20c3c4d6374c8dfd06446848 + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=005f8c03ac2d9313e2cc5b30dcc9133cbf8c53671af5e80032bb36b9279cc41c8742f859b3c64097ef1ba62a1c4b6d02d9ec1a6e +INFO=4341565369641253e69cd9f2692f10c4d09c1be8d1967445c4e4596ffa61c2cea1b2c3d4e5f776d55088934bc8d5d2 +EXPECT=00059c8673b4d3e269147e91591385d5636e793cc36690ae + +HASH=SHA1 +VARIANT=DIGEST +SECRET=81f3d2ad1f70fd67a374547d59506a04d545f4e869f00fa0 +INFO=434156536964e63969525e54d806789d7121a1b2c3d4e581597a0e979d5c99a79b1789b41ae57fef5b916f85a1e449 +EXPECT=6ff62398511a8a243513781f02d9e50d412c247c84a01dac17f8d8d74bb5ddc5c5d156eb0173e597cab4a276aed4f42d74b5a105666cddd26efc1fa130e1b062f2431c974eca6bc81c8fdc0a78088271cbd3aae0972d37016a293b59fb5656ff169da3ac23cc39723fa887342346fb5859b63ebb86eb19ccff6e314253b9a771 + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=81f3d2ad1f70fd67a374547d59506a04d545f4e869f00fa0 +INFO=434156536964e63969525e54d806789d7121a1b2c3d4e581597a0e979d5c99a79b1789b41ae57fef5b916f85a1e449 +EXPECT=94a283be5d007b1729f8a7ed1a9bf0361435131c4477e750959bd64426c1fa16df07f848e1ba90d8d3196424de928cdb8a5eda08ef03a5ca907b07faa0d4ac096a9dc7c5fa1f931336f864fdd9038b2dda14ca933c722657c90dd1c82c3a99af48fdb599a975498f023424c5a6cfe010dd800e42c55de57a5d75a6cd54e299b9 + +HASH=SHA-384 +VARIANT=DIGEST +SECRET=81f3d2ad1f70fd67a374547d59506a04d545f4e869f00fa0 +INFO=434156536964e63969525e54d806789d7121a1b2c3d4e581597a0e979d5c99a79b1789b41ae57fef5b916f85a1e449 +EXPECT=98989fa5f8de3098dfa089a454c24586f75f5bdc1e860d6088f42d9cc129bb462ae243b7922a6c276891bee5ca79b0744b7ef4cb419db1e4ab80d67c873cb62912cb6cef80f17198e02ff590af59faf17e3128b80879606fa346f14930597005d2be607b08b4361a403a28f18f5bc485a8c53921fbe8adcb35e64d4dc9227a5e + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=81f3d2ad1f70fd67a374547d59506a04d545f4e869f00fa0 +INFO=434156536964e63969525e54d806789d7121a1b2c3d4e581597a0e979d5c99a79b1789b41ae57fef5b916f85a1e449 +EXPECT=8501c55696448de9e6b452cd56b022cba6826e8d4fd3d1f75346ef4698169b2642ffedad53e948ab42b923f54083244879b735e5e478139cb500fa7972d79f6c4cfdbc243f34b37bede60315c7e92500fee77cdd1c6eff97ff6a181d39dfe01350ad1702eb37441256bca3d0ddeb6043daebafc821afa2bae9a5457515ddee56 + +# Tests that follow were sourced from https://github.com/patrickfav/singlestep-kdf + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=4d7920736563726574 +INFO=00000000000000000000000000000000 +EXPECT=5f225b4801843ed861b95f5b0a3afd78473498f0b5cb6d7769e67458e057da8c0311 + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=616e6f74686572206f6e65 +INFO=9014bf55dc1e03babb5ca1c1323a1e5b +EXPECT=4f0a3cf7d52987ccd470d4a8f9d41da9bc6dcf4945c1e522c04fd0c070c397ddb7f4 + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=65306334326336353234373139 +INFO=dbebe4f7dde938229f26651e011f7bbd +EXPECT=d9151c3f36f6980951d84cca75ade71b + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=cf80cf80cf80cf80cf80cf80cf80cf80 +INFO=676c65eb966200b04a2bb870d7ed20ce +EXPECT=c5bb681f1a04713ee7be14e0190676773b0ff63561892fac030b18cca38955369cfc32cdd956ef6e2e4301deb61d049a4d82e57a434168bc5ae084e0df15c0a0d8232d7a791088446b66e612753d36649e70a234a360b611baa07e4a6a7c660db2a1b56acba42d6d3d83b3ce51c787c544bb14b1c94b780fab5c0f966efd80f4a71cd4f267f816a3bb1ec8ceddcd810d1665742c8f68767cd9d7f87ad97792edc6896b6518 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=4d7920736563726574 +INFO=00000000000000000000000000000000 +EXPECT=eba887dca269a550a3882f06f3b1c30058751bc4ec5375e5435e525aeca9782e6311 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=616e6f74686572206f6e65 +INFO=9014bf55dc1e03babb5ca1c1323a1e5b +SALT=ebf4c1e001f26879afc76c7a45ac9541 +EXPECT=8a6484427e5231642a83e7a01fd410040dda5bf3b3d34ec626a8603ac1a5e2e38f02 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=65306334326336353234373139 +INFO=dbebe4f7dde938229f26651e011f7bbd +EXPECT=cceb4536d8431c4d91a5c6f061955aac + +HASH=SHA-256 +VARIANT=HMAC +SECRET=cf80cf80cf80cf80cf80cf80cf80cf80 +INFO=676c65eb966200b04a2bb870d7ed20ce +SALT=1aab1829c8b7ed941b3dc8359dd1f402 +EXPECT=2933b1a656efd556c421533e4fab685c4a9c32f15099a357a73a59c6acebb01b9685631d6208992413c2397c58e8020e588cc16f1f1b470a411ab65d6a0503e3728be789e54e313d49bd1edd606757db6c605ed1e346dd6841afd895379ba09dde046a19dce0a8d49b3ed5671d448e141da5f6bcf3aa5313affd8a14784c424b6d5087aa038ab13db398abbd50dfd39d1134dbe88e308373861d7acf1d79b740f717193d5b + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=4d7920736563726574 +INFO=00000000000000000000000000000000 +EXPECT=8930b01ea45ed7c97c31b5d98a84c48c198c3e5db28241ba9c8417ff1986b53bb4f0 + +# Test Vector from https://github.com/openssl/openssl/blob/9fcf57b45985336b04579dd317d0dc990a9c062b/test/evp_kdf_test.c#L901 +HASH=SHA-224 +VARIANT=DIGEST +SECRET=6dbdc23f045488e4062757b06b9ebae183fc5a5946d80db93fec6f62ec07e3727f0126aed12ce4b262f47d48d54287f81d474c7c3b1850e9 +INFO=a1b2c3d4e54341565369643c832e9849dcdba71e9a3139e606e095de3c264a66e98a165854cd07989b1ee0ec3f8dbe +EXPECT=a462de16a89de8466ef5460b47b8 + +# Translated Vectors below from https://github.com/openssl/openssl/blob/9fcf57b45985336b04579dd317d0dc990a9c062b/test/recipes/30-test_evp_data/evpkdf_ss.txt +HASH=SHA1 +VARIANT=DIGEST +SECRET=d09a6b1a472f930db4f5e6b967900744 +INFO=b117255ab5f1b6b96fc434b0 +EXPECT=b5a3c52e97ae6e8c5069954354eab3c7 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=343666c0dd34b756e70f759f14c304f5 +INFO=722b28448d7eab85491bce09 +EXPECT=1003b650ddd3f0891a15166db5ec881d + +HASH=SHA1 +VARIANT=DIGEST +SECRET=b84acf03ab08652dd7f82fa956933261 +INFO=3d8773ec068c86053a918565 +EXPECT=1635dcd1ce698f736831b4badb68ab2b + +HASH=SHA1 +VARIANT=DIGEST +SECRET=8cc24ca3f1d1a8b34783780b79890430 +INFO=f08d4f2d9a8e6d7105c0bc16 +EXPECT=b8e716fb84a420aed4812cd76d9700ee + +HASH=SHA1 +VARIANT=DIGEST +SECRET=b616905a6f7562cd2689142ce21e42a3 +INFO=ead310159a909da87e7b4b40 +EXPECT=1b9201358c50fe5d5d42907c4a9fce78 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=3f57fd3fd56199b3eb33890f7ee28180 +INFO=7a5056ba4fdb034c7cb6c4fe +EXPECT=e51ebd30a8c4b8449b0fb29d9adc11af + +HASH=SHA1 +VARIANT=DIGEST +SECRET=fb9fb108d104e9f662d6593fc84cde69 +INFO=5faf29211c1bdbf1b2696a7c +EXPECT=7a3a7e670656e48c390cdd7c51e167e0 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=237a39981794f4516dccffc3dda28396 +INFO=62ed9528d104c241e0f66275 +EXPECT=0c26fc9e90e1c5c5f943428301682045 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=b9b6c45f7279218fa09894e06366a3a1 +INFO=0f384339670aaed4b89ecb7e +EXPECT=ee5fad414e32fad5d52a2bf61a7f6c72 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=08b7140e2cd0a4abd79171e4d5a71cad +INFO=099211f0d8a2e02dbb5958c0 +EXPECT=6162f5142e057efafd2c4f2bad5985a1 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a2 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f4853 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493d + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759a + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac704 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbe + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf1050 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f3 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8b + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f22 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f227688 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abf + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e811a + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e811a568d + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e811a568d480d + +HASH=SHA1 +VARIANT=DIGEST +SECRET=ebe28edbae5a410b87a479243db3f690 +INFO=e60dd8b28228ce5b9be74d3b +EXPECT=b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e811a568d480d9192 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=d7e6 +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=31e798e9931b612a3ad1b9b1008faa8c + +HASH=SHA1 +VARIANT=DIGEST +SECRET=4646779d +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=139f68bcca879b490e268e569087d04d + +HASH=SHA1 +VARIANT=DIGEST +SECRET=d9811c81d4c6 +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=914dc4f09cb633a76e6c389e04c64485 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=8838f9d99ec46f09 +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=4f07dfb6f7a5bf348689e08b2e29c948 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=3e0939b33f34e779f30e +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=b42c7a98c23be19d1187ff960e87557f + +HASH=SHA1 +VARIANT=DIGEST +SECRET=f36230cacca4d245d303058c +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=50f2068d8010d355d56c5e34aaffbc67 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=7005d32c3d4284c73c3aefc70438 +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=66fd712ccf5462bbd41e89041ea7ea26 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=c01c83150b7734f8dbd6efd6f54d7365 +INFO=0bbe1fa8722023d7c3da4fff +EXPECT=5c5edb0ceda9cd0c7f1f3d9e239c67d5 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=9949 +EXPECT=33c83f54ed00fb1bccd2113e88550941 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=17144da6 +EXPECT=a999c28961424cab35ec06015e8c376a + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=dffdee1062eb +EXPECT=4101ad50e626ed6f957bff926dfbb7db + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=9f365043e23b4648 +EXPECT=4d3e4b971b88771f229df9f564984832 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=a885a0c4567ddc4f96da +EXPECT=bebbc30f5a83df5e9c9b57db33c0c879 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=c9d86183295bfe4c3d85f0fd +EXPECT=87c947e45407db63eb94cbaa02d14e94 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=825fadce46964236a486732c5dad +EXPECT=192370a85ff78e3c0245129d9b398558 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=da69f1dbbebc837480af692e7e9ee6b9 +INFO=5c0b5eb3ac9f342347d73d7a521723aa +EXPECT=c7b7634fd809383e87c4b1b3e728be56 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=8d7a4e7d5cf34b3f74873b862aeb33b7 +EXPECT=6a5594f402f74f69 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=9b208e7ee1e641fac1dff48fc1beb2d2 +EXPECT=556ed67e24ac0c7c46cc432da8bdb23c + +HASH=SHA1 +VARIANT=DIGEST +SECRET=4d2572539fed433211da28c8a0eebac3 +EXPECT=5a4054c59c5b92814025578f43c1b79fe84968fc284e240b + +HASH=SHA1 +VARIANT=DIGEST +SECRET=4e1e70c9886819a31bc29a537911add9 +EXPECT=ddbfc440449aab4131c6d8aec08ce1496f2702241d0e27cc155c5c7c3cda75b5 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=68f144c952528e540c686dc353b766f2 +EXPECT=59ed66bb6f54a9688a0b891d0b2ea6743621d9e1b5cc098cf3a55e6f864f9af8a95e4d945d2f987f + +HASH=SHA1 +VARIANT=DIGEST +SECRET=b66c9d507c9f837fbe60b6675fdbf38b +EXPECT=c282787ddf421a72fc88811be81b08d0d6ab66c92d1011974aa58335a6bbbd62e9e982bfae5929865ea1d517247089d2 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=34e730b49e46c7ed2fb25975a4cccd2d +EXPECT=39e76e6571cb00740260b9070accbdcc4a492c295cbef33d9e37dac21e5e9d07e0f12dc7063d2172641475d4e08b8e3712fb26a10c8376b8 + +HASH=SHA1 +VARIANT=DIGEST +SECRET=e340d87e2d7adbc1b95ec2dbdc3b82be +EXPECT=a660c0037a53f76f1e7667043f5869348ad07ac0e272e615ce31f16d4ab90d4b35fe5c370c0010ce79aff45682c6fb8b97f9a05b7d40b5af3c62999a10df9c6d + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=afc4e154498d4770aa8365f6903dc83b +INFO=662af20379b29d5ef813e655 +EXPECT=f0b80d6ae4c1e19e2105a37024e35dc6 + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=108cf63318555c787fa578731dd4f037 +INFO=53191b1dd3f94d83084d61d6 +EXPECT=0ad475c1826da3007637970c8b92b993 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=6ee6c00d70a6cd14bd5a4e8fcfec8386 +SALT=532f5131e0a2fecc722f87e5aa2062cb +INFO=861aa2886798231259bd0314 +EXPECT=13479e9a91dd20fdd757d68ffe8869fb + +HASH=SHA-256 +VARIANT=HMAC +SECRET=cb09b565de1ac27a50289b3704b93afd +SALT=d504c1c41a499481ce88695d18ae2e8f +INFO=5ed3768c2c7835943a789324 +EXPECT=f081c0255b0cae16edc6ce1d6c9d12bc + +HASH=SHA-256 +VARIANT=HMAC +SECRET=98f50345fd970639a1b7935f501e1d7c +SALT=3691939461247e9f74382ae4ef629b17 +INFO=6ddbdb1314663152c3ccc192 +EXPECT=56f42183ed3e287298dbbecf143f51ac + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a72b0076221727eca4d3ef8f4d88ac96 +SALT=397dc6807de2c1d5ba52e03c4e6c7a19 +INFO=12379bd7873a7dbabe894ac8 +EXPECT=26c0f937e8ca337a859b6c092fe22b9a + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0b09bf8ebe1e85a049174c521e35be64 +SALT=313d29bbeaa5ac9e52278f7619d29d93 +INFO=e2ac98de1486959bfc6363c0 +EXPECT=4bfdf78782a45e2a5858edb851c5783c + +HASH=SHA-256 +VARIANT=HMAC +SECRET=e907ad4fe811ee047af77e0c4418226a +SALT=5000ef57104ca2e86a5fec5883ea4ea8 +INFO=c4ee443920f2b7542eee2a24 +EXPECT=06bfbd9571462c920a5a1b589c765383 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=608dae15fe8b906d2dc649815bdee148 +SALT=742cc5a02a24d09c66fd9da0d0c571f6 +INFO=ba60ff781e2756cba07f6524 +EXPECT=7f7f9e5d8f89a8edd10289f1d690f629 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=eb39e8dc7c40b906216108e2592bb6cd +SALT=af9f612da575c1afc8c4afff4ced34e1 +INFO=84b7f0628df0cb22baaa279a +EXPECT=5202576c69c6276daedf4916de250d19 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=4bac0c1a963b8cf6933beb2ad191a31e +SALT=debd24d71a1a7ae77f7e3aa24d939635 +INFO=9e51c8593cec92c89e82439a +EXPECT=ecb9889f9004f80716b56c44910f160c + +HASH=SHA-256 +VARIANT=HMAC +SECRET=8aa41e3c8076ea01ca6789dd18709a68 +SALT=7c9dacc409cde7b05efdae07bd9973db +INFO=52651f0f2e858bbfbacb2533 +EXPECT=b8683c9a982e0826d659a1ab77a603d7 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d3 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d8 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d89102 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be0 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f2 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c504 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a1 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca6 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd99 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995de + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c710 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca9091 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab6 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe19 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe193c95 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe193c9546d4 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe193c9546d45849 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=02b40d33e3f685aeae677ac344eeaf77 +SALT=0ad52c9357c85e4781296a36ca72039c +INFO=c67c389580128f18f6cf8592 +EXPECT=be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe193c9546d45849133d + +HASH=SHA-256 +VARIANT=HMAC +SECRET=f4e1 +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=3f661ec46fcc1e110b88f33ee7dbc308 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=253554e5 +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=73ccb357554ca44967d507518262e38d + +HASH=SHA-256 +VARIANT=HMAC +SECRET=e10d0e0bc95b +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=c4f1cf190980b6777bb35107654b25f9 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=451f7f2c23c51326 +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=ddb2d7475d00cc65bff6904b4f0b54ba + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0f27277ee800d6cc5425 +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=1100a6049ae9d8be01ab3829754cecc2 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=20438ff1f26390dbc3a1a6d0 +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=5180382f740444ada597197f98e73e1e + +HASH=SHA-256 +VARIANT=HMAC +SECRET=b74a149a161546f8c20b06ac4ed4 +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=44f676e85c1b1a8bbc3d319218631ca3 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=8aa7df46b8cb3fe47228494f4e116b2c +SALT=3638271ccd68a25dc24ecddd39ef3f89 +INFO=348a37a27ef1282f5f020dcc +EXPECT=ebb24413855a0a3249960d0de0f4750d + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=d851 +EXPECT=5dbe10ead8f81a81a29072eca4501658 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=b04da03c +EXPECT=0a08d7616dcbec25a36f1936b82992ca + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=f9e8b47eade3 +EXPECT=84a29697445179b662d85dbc59bf8042 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=5b141bfa54fcf824 +EXPECT=be7660c840644cec84d67d95ba7ebf2d + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=736e7ddb856f0ba14744 +EXPECT=e3010b1fbcb02fd8baa8449ac71d0c62 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=c54320ff6e7d1a3b0b3aea00 +EXPECT=df0ac84982999cda676e4cbf707c42f0 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=37ab143e1b4ab61d0294ea8afbc7 +EXPECT=93eec7f4dda18b7e710dbbd7570ebd13 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a678236b6ac82077b23f73a510c1d0e2 +SALT=46ee4f36a4167a09cde5a33b130c6e1c +INFO=c3146575d2c60981511e700902fc2ac1 +EXPECT=e9125f77d699faa53d5bc48f3fc2f7d0 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=1ae1 +INFO=97ed3540c7466ab27395fe79 +EXPECT=ddf7eedcd997eca3943d4519aaf414f4 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=3bda13b6 +INFO=97ed3540c7466ab27395fe79 +EXPECT=ec783ca20501df3cacac5ab4adbc6427 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=c792f52e5876 +INFO=97ed3540c7466ab27395fe79 +EXPECT=9303a2562e6f8c418e3fcc081b94bdcf + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=a9b7a64840d52633 +INFO=97ed3540c7466ab27395fe79 +EXPECT=aab6b0dc19bae0dd7fa02391ac3d6ef1 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=8f62a3ec15cdf9b3522f +INFO=97ed3540c7466ab27395fe79 +EXPECT=1516d5ed7f46474d250408b0864647cf + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=55ed67cbdc98ed8e45214704 +INFO=97ed3540c7466ab27395fe79 +EXPECT=38bf96a3d737a84dc10a835d340b6866 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=e4946aff3b2ab891b311234c77bc +INFO=97ed3540c7466ab27395fe79 +EXPECT=3ddd870471ff028a63c5f1bacc7e5b5c + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0031558fddb96e3db2e0496026302055 +SALT=91e8378de5348cea41f84c41e8546e34 +INFO=97ed3540c7466ab27395fe79 +EXPECT=bf1eb0eab488b2393ad6a1c2eb804381 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=4ce16564db9615f75d46c6a9837af7ca +SALT=6199187690823def2037e0632577c6b1 +EXPECT=0a102289b16cbf4b + +HASH=SHA-256 +VARIANT=HMAC +SECRET=2578fe1116e27e3a5e8e935e892e12eb +SALT=6199187690823def2037e0632577c6b1 +EXPECT=dd5773998893ad5a93f9819c8e798aab + +HASH=SHA-256 +VARIANT=HMAC +SECRET=e9dd8bd75f29661e61703346bbf2df47 +SALT=6199187690823def2037e0632577c6b1 +EXPECT=32136643daa64aaac0e2886364f157ba923d7b36ada761eb + +HASH=SHA-256 +VARIANT=HMAC +SECRET=e4640d3752cf48186a8ad2d7d4a81210 +SALT=6199187690823def2037e0632577c6b1 +EXPECT=6379d59efbe02576663af5efaccb9d063f596a22c8e1fed12cde7cdd7f327e88 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=3bd9a074a219d62273c3f639659a3ecd +SALT=6199187690823def2037e0632577c6b1 +EXPECT=cc45eb2ab80272c1e082b4f167ee4e086f12af3fbd0c812dda5568fea702928999cde3899cffc8a8 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=2147c0fb1c7587b22fa44ce3bf3d8f5b +SALT=6199187690823def2037e0632577c6b1 +EXPECT=4e3a8827fcdb214686b35bfcc497ca69dccb78d3464aa4af0704ec0fba03c7bb10b9a4e31e27b1b2379a32e46935309c + +HASH=SHA-256 +VARIANT=HMAC +SECRET=2c2438b6321fed7a9eac200b91b3ac30 +SALT=6199187690823def2037e0632577c6b1 +EXPECT=b402fda16e1c2719263be82158972c9080a7bafcbe0a3a6ede3504a3d5c8c0c0e00fe7e5f6bb3afdfa4d661b8fbe4bd7b950cfe0b2443bbd + +HASH=SHA-256 +VARIANT=HMAC +SECRET=0ffa4c40a822f6e3d86053aefe738eac +SALT=6199187690823def2037e0632577c6b1 +EXPECT=0486d589aa71a603c09120fb76eeab3293eee2dc36a91b23eb954d6703ade8a7b660d920c5a6f7bf3898d0e81fbad3a680b74b33680e0cc6a16aa616d078b256 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a801d997ed539ae9aa05d17871eb7fab +INFO=03697296e42a6fdbdb24b3ec +EXPECT=1a5efa3aca87c1f4 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=e9624e112f9e90e7bf8a749cf37d920c +INFO=03697296e42a6fdbdb24b3ec +EXPECT=ee93ca3986cc43516ae4e29fd7a90ef1 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=a92acdee54a84a4564d4782d47801ec0 +INFO=03697296e42a6fdbdb24b3ec +EXPECT=3116b87eaffaa0cc48a72e6c1574df335d706f7c860b44e9 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=e60d902e63b1a2bf5dab733cadb47b10 +INFO=03697296e42a6fdbdb24b3ec +EXPECT=3fde6c078dd6dc65aacf62beafa39398d2b3d7cfb4b0ee4807bfc98a15330eef + +HASH=SHA-256 +VARIANT=HMAC +SECRET=d3b747a1d1584a0fc5aefcd4dd8ef9c3 +INFO=03697296e42a6fdbdb24b3ec +EXPECT=2c4363597d42f9f8736e8050b4a6dd033d7ddac6f7211c4810ef74aff01f101d885767d7ae6f1d7f + +HASH=SHA-256 +VARIANT=HMAC +SECRET=119559a2c0a8888e9c95b9989a460d97 +INFO=03697296e42a6fdbdb24b3ec +EXPECT=97922585f69adf484930cf22b8378c797694438502fa47e2f19f0fee97ca11451f3bc81a20c1d74964c63ab2d5df1985 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=807f375266988df5d0ae878efac424fa +INFO=03697296e42a6fdbdb24b3ec +EXPECT=ba78ef8ab720fc583bb64581917634fca230876cc344e46b44fe61f3bdab556ee753743b78db4b16c0fcd8f987aebad15d0b7b13a10f6819 + +HASH=SHA-256 +VARIANT=HMAC +SECRET=f7906f870b256753b5bc3ef408e47e9b +INFO=03697296e42a6fdbdb24b3ec +EXPECT=96bee2ae234f98c285aa970bd54c2e2891febf734bad58a91dc7a97490b6b05fe539f2156ae3acd2e661eced0d59084fda340cd1ba3daa7ca2a550d7b1c19462 + +HASH=SHA-512 +VARIANT=HMAC +SECRET=73b6e2ede34aae5680e2289e611ffc3a +SALT=28df8439747d5a9b502e0838ca6999b2 +INFO=232941631fc04dd82f727a51 +EXPECT=b0d36cd7d6b23b48ca6f89901bb784ec + +HASH=SHA-512 +VARIANT=HMAC +SECRET=abb7d7554c0de41cada5826a1f79d76f +INFO=a80b9061879365b1669c87a8 +EXPECT=71e29fff69198eca92f5180bcb281fbdaf409ec7c99ca704b1f56e782d3c4db10cb4158e6634d793a46c13bffb6bdb71a01101936ea9b20f7dbe302558b1356c + +HASH=SHA1 +VARIANT=DIGEST +SECRET=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +INFO=307e300a06082b06010502030601a01f041d301ba0071b0553552e5345a110300ea003020101a10730051b036c6861a12904273025a0071b0553552e5345a11a3018a003020101a111300f1b066b72627467741b0553552e5345a22404223020a003020112a10c040aaaaaaaaaaaaaaaaaaaaaa20b0409bbbbbbbbbbbbbbbbbb +EXPECT=e6ab38c9413e035bb079201ed0b6b73d8d49a814a737c04ee6649614206f73ad + +HASH=SHA-256 +VARIANT=DIGEST +SECRET=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +INFO=307e300a06082b06010502030602a01f041d301ba0071b0553552e5345a110300ea003020101a10730051b036c6861a12904273025a0071b0553552e5345a11a3018a003020101a111300f1b066b72627467741b0553552e5345a22404223020a003020112a10c040aaaaaaaaaaaaaaaaaaaaaa20b0409bbbbbbbbbbbbbbbbbb +EXPECT=77ef4e48c420ae3fec75109d7981697eed5d295c90c62564f7bfd101fa9bc1d5 + +HASH=SHA-512 +VARIANT=DIGEST +SECRET=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +INFO=307e300a06082b06010502030603a01f041d301ba0071b0553552e5345a110300ea003020101a10730051b036c6861a12904273025a0071b0553552e5345a11a3018a003020101a111300f1b066b72627467741b0553552e5345a22404223020a003020110a10c040aaaaaaaaaaaaaaaaaaaaaa20b0409bbbbbbbbbbbbbbbbbb +EXPECT=d3c78b78d75313e9a926f75dfb012363fa17fa01db + diff --git a/tst/com/amazon/corretto/crypto/provider/test/ConcatenationKdfTest.java b/tst/com/amazon/corretto/crypto/provider/test/ConcatenationKdfTest.java new file mode 100644 index 00000000..47046d38 --- /dev/null +++ b/tst/com/amazon/corretto/crypto/provider/test/ConcatenationKdfTest.java @@ -0,0 +1,155 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.corretto.crypto.provider.test; + +import static com.amazon.corretto.crypto.provider.test.TestUtil.bcDigest; +import static com.amazon.corretto.crypto.provider.test.TestUtil.getEntriesFromFile; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import com.amazon.corretto.crypto.provider.ConcatenationKdfSpec; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.util.stream.Stream; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator; +import org.bouncycastle.crypto.params.KDFParameters; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceAccessMode; +import org.junit.jupiter.api.parallel.ResourceLock; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@ExtendWith(TestResultLogger.class) +@Execution(ExecutionMode.CONCURRENT) +@ResourceLock(value = TestUtil.RESOURCE_GLOBAL, mode = ResourceAccessMode.READ) +public class ConcatenationKdfTest { + + @Test + public void concatenationKdfsAreNotAvailableInFipsMode() { + assumeTrue(TestUtil.isFips()); + Stream.of( + "ConcatenationKdfWithSHA256", + "ConcatenationKdfWithSHA384", + "ConcatenationKdfWithSHA512", + "ConcatenationKdfWithHmacSHA256", + "ConcatenationKdfWithHmacSHA512") + .forEach( + alg -> + assertThrows( + NoSuchAlgorithmException.class, + () -> SecretKeyFactory.getInstance(alg, TestUtil.NATIVE_PROVIDER))); + } + + @Test + public void secretLengthCannotBeZero() { + assertThrows( + IllegalArgumentException.class, () -> new ConcatenationKdfSpec(new byte[0], 1, "name")); + } + + @Test + public void outputLengthCannotBeZeroOrNegative() { + assertThrows( + IllegalArgumentException.class, () -> new ConcatenationKdfSpec(new byte[0], 0, "name")); + assertThrows( + IllegalArgumentException.class, () -> new ConcatenationKdfSpec(new byte[0], -1, "name")); + } + + // The rest of the tests are only available in non-FIPS mode. + @Test + public void concatenationKdfExpectsConcatenationKdfSpecAsKeySpec() throws Exception { + assumeFalse(TestUtil.isFips()); + final SecretKeyFactory skf = + SecretKeyFactory.getInstance("ConcatenationKdfWithSha256", TestUtil.NATIVE_PROVIDER); + assertThrows( + InvalidKeySpecException.class, () -> skf.generateSecret(new PBEKeySpec(new char[4]))); + } + + @Test + public void concatenationKdfWithEmptyInfoIsFine() throws Exception { + assumeFalse(TestUtil.isFips()); + final SecretKeyFactory skf = + SecretKeyFactory.getInstance("ConcatenationKdfWithSha256", TestUtil.NATIVE_PROVIDER); + final ConcatenationKdfSpec spec = new ConcatenationKdfSpec(new byte[1], 10, "name"); + assertEquals(0, spec.getInfo().length); + assertNotNull(skf.generateSecret(spec)); + } + + @Test + public void concatenationKdfHmacWithEmptySaltIsFine() throws Exception { + assumeFalse(TestUtil.isFips()); + final SecretKeyFactory skf = + SecretKeyFactory.getInstance("ConcatenationKdfWithHmacSha256", TestUtil.NATIVE_PROVIDER); + final ConcatenationKdfSpec spec1 = new ConcatenationKdfSpec(new byte[1], 10, "name"); + assertEquals(0, spec1.getInfo().length); + assertEquals(0, spec1.getSalt().length); + assertNotNull(skf.generateSecret(spec1)); + + final ConcatenationKdfSpec spec2 = + new ConcatenationKdfSpec(new byte[1], 10, "name", new byte[10]); + assertEquals(10, spec2.getInfo().length); + assertEquals(0, spec2.getSalt().length); + assertNotNull(skf.generateSecret(spec2)); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("sskdfKatTests") + public void concatenationKdfKatTests(final RspTestEntry entry) throws Exception { + assumeFalse(TestUtil.isFips()); + final String digest = jceDigestName(entry.getInstance("HASH")); + assumeFalse("SHA1".equals(digest) || "SHA224".equals(digest)); + final boolean digestPrf = entry.getInstance("VARIANT").equals("DIGEST"); + final byte[] expected = entry.getInstanceFromHex("EXPECT"); + final byte[] secret = entry.getInstanceFromHex("SECRET"); + final byte[] info = entry.getInstanceFromHex("INFO"); + + final ConcatenationKdfSpec spec; + if (entry.contains("SALT")) { + spec = + new ConcatenationKdfSpec( + secret, expected.length, "SECRET_KEY", info, entry.getInstanceFromHex("SALT")); + } else { + spec = new ConcatenationKdfSpec(secret, expected.length, "SECRET_KEY", info); + } + + final String alg = "ConcatenationKdfWith" + (digestPrf ? "" : "Hmac") + digest; + + final SecretKeyFactory skf = SecretKeyFactory.getInstance(alg, TestUtil.NATIVE_PROVIDER); + final byte[] actual = skf.generateSecret(spec).getEncoded(); + assertArrayEquals(expected, actual); + + if (digestPrf) { + // Bouncy Castle implements the digest variant. Here we check that ACCP is also producing the + // same result as BC. + assertArrayEquals(bcConcatenationKdf(digest, spec), actual); + } + } + + private static String jceDigestName(final String digest) { + if (digest.contains("-")) { + return "SHA" + digest.substring(4); + } + return digest; + } + + private static Stream sskdfKatTests() throws Exception { + return getEntriesFromFile("sskdf.txt", false); + } + + private static byte[] bcConcatenationKdf(final String digest, final ConcatenationKdfSpec spec) { + final byte[] result = new byte[spec.getOutputLen()]; + final KDFParameters kdfParameters = new KDFParameters(spec.getSecret(), spec.getInfo()); + final ConcatenationKDFGenerator kdf = new ConcatenationKDFGenerator(bcDigest(digest)); + kdf.init(kdfParameters); + kdf.generateBytes(result, 0, result.length); + return result; + } +} diff --git a/tst/com/amazon/corretto/crypto/provider/test/RspTestEntry.java b/tst/com/amazon/corretto/crypto/provider/test/RspTestEntry.java index b730f0e1..f370068a 100644 --- a/tst/com/amazon/corretto/crypto/provider/test/RspTestEntry.java +++ b/tst/com/amazon/corretto/crypto/provider/test/RspTestEntry.java @@ -59,6 +59,15 @@ public String getInstance(final String field) { return getInstance().get(field); } + /** + * Returns true if the specific entry has the provided field. + * + * @see {@link #getInstance()} + */ + public boolean contains(final String field) { + return getInstance().containsKey(field); + } + /** * Returns a specific entry from this test case after interpreting it as hex-encoded binary. * diff --git a/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java b/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java index fe8dd136..04cfb503 100644 --- a/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java +++ b/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java @@ -34,6 +34,12 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.digests.SHA1Digest; +import org.bouncycastle.crypto.digests.SHA224Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA384Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.jupiter.api.Assumptions; @@ -462,9 +468,11 @@ public static synchronized void restoreProviders(final Provider[] providers) { } } - public static Stream getEntriesFromFile(final String fileName) throws IOException { + public static Stream getEntriesFromFile( + final String fileName, final boolean isCompressed) throws IOException { final File rsp = new File(System.getProperty("test.data.dir"), fileName); - final InputStream is = new GZIPInputStream(new FileInputStream(rsp)); + final InputStream is = + isCompressed ? new GZIPInputStream(new FileInputStream(rsp)) : new FileInputStream(rsp); final Iterator iterator = RspTestEntry.iterateOverResource(is, true); // Auto-closes stream final Spliterator split = @@ -472,6 +480,10 @@ public static Stream getEntriesFromFile(final String fileName) thr return StreamSupport.stream(split, false); } + public static Stream getEntriesFromFile(final String fileName) throws IOException { + return getEntriesFromFile(fileName, true); + } + public static int roundUp(final int i, final int m) { final int d = m - (i % m); return d == m ? i : (i + d); @@ -803,4 +815,21 @@ public static List genPattern(final long seed, final int choice, final } return constantPattern(inputLen, choice); } + + static Digest bcDigest(final String digest) { + switch (digest) { + case "SHA1": + return new SHA1Digest(); + case "SHA224": + return new SHA224Digest(); + case "SHA256": + return new SHA256Digest(); + case "SHA384": + return new SHA384Digest(); + case "SHA512": + return new SHA512Digest(); + default: + return null; + } + } }