package com.google.crypto.tink.subtle;
import com.google.crypto.tink.Aead;
import com.google.crypto.tink.HybridDecrypt;
import java.security.GeneralSecurityException;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.EllipticCurve;
import java.util.Arrays;
public final class EciesAeadHkdfHybridDecrypt implements HybridDecrypt {
private static final byte[] EMPTY_AAD = new byte[0];
private final ECPrivateKey recipientPrivateKey;
private final EciesHkdfRecipientKem recipientKem;
private final String hkdfHmacAlgo;
private final byte[] hkdfSalt;
private final EllipticCurves.PointFormatType ecPointFormat;
private final EciesAeadHkdfDemHelper demHelper;
public EciesAeadHkdfHybridDecrypt(
final ECPrivateKey recipientPrivateKey,
final byte[] hkdfSalt,
String hkdfHmacAlgo,
EllipticCurves.PointFormatType ecPointFormat,
EciesAeadHkdfDemHelper demHelper)
throws GeneralSecurityException {
this.recipientPrivateKey = recipientPrivateKey;
this.recipientKem = new EciesHkdfRecipientKem(recipientPrivateKey);
this.hkdfSalt = hkdfSalt;
this.hkdfHmacAlgo = hkdfHmacAlgo;
this.ecPointFormat = ecPointFormat;
this.demHelper = demHelper;
}
@Override
public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo)
throws GeneralSecurityException {
EllipticCurve curve = recipientPrivateKey.getParams().getCurve();
int headerSize = EllipticCurves.encodingSizeInBytes(curve, ecPointFormat);
if (ciphertext.length < headerSize) {
throw new GeneralSecurityException("ciphertext too short");
}
byte[] kemBytes = Arrays.copyOfRange(ciphertext, 0, headerSize);
byte[] symmetricKey =
recipientKem.generateKey(
kemBytes,
hkdfHmacAlgo,
hkdfSalt,
contextInfo,
demHelper.getSymmetricKeySizeInBytes(),
ecPointFormat);
Aead aead = demHelper.getAead(symmetricKey);
return aead.decrypt(Arrays.copyOfRange(ciphertext, headerSize, ciphertext.length), EMPTY_AAD);
}
}