-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConcatinationKDF: SSKDF from NIST.SP.800-56Cr2 Key Derivation #397
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <openssl/evp.h> | ||
#include <openssl/kdf.h> | ||
|
||
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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
* | ||
* <p>If info or salt is not provided, empty byte arrays are used. | ||
* | ||
* <p>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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should you validate the algorithmName here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The KDFs are used in different context. It's hard to come up with the exhaustive list of all acceptable algorithm names. |
||
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; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out this is unnecessary in a java docstring, and the linter will even remove the close tags. 🤦