in src/main/java/com/amazonaws/encryptionsdk/internal/CommittedKey.java [53:112]
public static CommittedKey generate(CryptoAlgorithm alg, SecretKey dataKey, byte[] nonce)
throws InvalidKeyException {
if (!alg.isCommitting()) {
throw new IllegalArgumentException("Algorithm does not support key commitment.");
}
if (nonce.length != alg.getCommitmentNonceLength()) {
throw new IllegalArgumentException("Invalid nonce size");
}
if (dataKey.getFormat() == null || !dataKey.getFormat().equalsIgnoreCase(RAW_DATA_FORMAT)) {
throw new IllegalArgumentException(
"Currently only RAW format keys are supported for HKDF algorithms. Actual format was "
+ dataKey.getFormat());
}
if (dataKey.getAlgorithm() == null
|| !dataKey.getAlgorithm().equalsIgnoreCase(alg.getDataKeyAlgo())) {
throw new IllegalArgumentException(
"DataKey of incorrect algorithm. Expected "
+ alg.getDataKeyAlgo()
+ " but was "
+ dataKey.getAlgorithm());
}
final byte[] rawDataKey = dataKey.getEncoded();
if (rawDataKey.length != alg.getDataKeyLength()) {
throw new IllegalArgumentException(
"DataKey of incorrect length. Expected "
+ alg.getDataKeyLength()
+ " but was "
+ rawDataKey.length);
}
final String macAlgorithm;
switch (alg.getKeyCommitmentAlgo_()) {
case HKDF_SHA_512:
macAlgorithm = HMAC_SHA_512;
break;
default:
throw new UnsupportedOperationException(
"Support for commitment with " + alg.getKeyCommitmentAlgo_() + " not yet built.");
}
HmacKeyDerivationFunction kdf = null;
try {
kdf = HmacKeyDerivationFunction.getInstance(macAlgorithm);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
kdf.init(rawDataKey, nonce);
final byte[] commitment = kdf.deriveKey(COMMITKEY_LABEL, alg.getCommitmentLength());
// Clone to prevent modification of the master copy
final byte[] deriveKeyLabel = DERIVE_KEY_LABEL_TEMPLATE.clone();
final short algId = alg.getValue();
deriveKeyLabel[0] = (byte) ((algId >> 8) & 0xFF);
deriveKeyLabel[1] = (byte) (algId & 0xFF);
SecretKey ek =
new SecretKeySpec(kdf.deriveKey(deriveKeyLabel, alg.getKeyLength()), alg.getKeyAlgo());
return new CommittedKey(ek, commitment);
}