in DynamoDbEncryption/runtimes/java/src/main/sdkv1/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/DirectKmsMaterialProvider.java [179:234]
public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) {
final Map<String, String> ec = new HashMap<>();
ec.put("*" + CONTENT_KEY_ALGORITHM + "*", dataKeyDesc);
ec.put("*" + SIGNING_KEY_ALGORITHM + "*", sigKeyDesc);
populateKmsEcFromEc(context, ec);
final String keyId = selectEncryptionKeyId(context);
if (StringUtils.isNullOrEmpty(keyId)) {
throw new DynamoDBMappingException("Encryption key id is empty.");
}
final GenerateDataKeyRequest req = appendUserAgent(
new GenerateDataKeyRequest()
);
req.setKeyId(keyId);
// NumberOfBytes parameter is used because we're not using this key as an AES-256 key,
// we're using it as an HKDF-SHA256 key.
req.setNumberOfBytes(256 / 8);
req.setEncryptionContext(ec);
final GenerateDataKeyResult dataKeyResult = generateDataKey(req, context);
final Map<String, String> materialDescription = new HashMap<>();
materialDescription.putAll(description);
materialDescription.put(COVERED_ATTR_CTX_KEY, KEY_COVERAGE);
materialDescription.put(KEY_WRAPPING_ALGORITHM, "kms");
materialDescription.put(CONTENT_KEY_ALGORITHM, dataKeyDesc);
materialDescription.put(SIGNING_KEY_ALGORITHM, sigKeyDesc);
materialDescription.put(
ENVELOPE_KEY,
Base64.encodeToString(toArray(dataKeyResult.getCiphertextBlob()))
);
final Hkdf kdf;
try {
kdf = Hkdf.getInstance(KDF_ALG);
} catch (NoSuchAlgorithmException e) {
throw new DynamoDBMappingException(e);
}
kdf.init(toArray(dataKeyResult.getPlaintext()));
final SecretKey encryptionKey = new SecretKeySpec(
kdf.deriveKey(KDF_ENC_INFO, dataKeyLength / 8),
dataKeyAlg
);
final SecretKey signatureKey = new SecretKeySpec(
kdf.deriveKey(KDF_SIG_INFO, sigKeyLength / 8),
sigKeyAlg
);
return new SymmetricRawMaterials(
encryptionKey,
signatureKey,
materialDescription
);
}