in java/remoteprovisioning/CborUtil.java [88:128]
private static CBORObject encodeEncryptMessageInternal(
byte[] plaintext, byte[] aesKey, CBORObject ephemeralPubKey, byte[] keyId)
throws CborException, CryptoException {
SecureRandom rand = new SecureRandom();
byte[] iv = new byte[16];
rand.nextBytes(iv);
// A COSE_Encrypt message is a CBOR array with 4 entries
CBORObject encMsg = CBORObject.NewArray();
CBORObject protectedHeaders = CBORObject.NewMap();
protectedHeaders.Add(HeaderKeys.Algorithm.AsCBOR(), AlgorithmID.AES_GCM_256.AsCBOR());
byte[] aad = buildEncStructure(protectedHeaders.EncodeToBytes(), null);
CBORObject unprotectedHeaders = CBORObject.NewMap();
unprotectedHeaders.Add(HeaderKeys.IV.AsCBOR(), CBORObject.FromObject(iv));
CBORObject content = CBORObject.FromObject(CryptoUtil.encrypt(plaintext, aad, aesKey, iv));
CBORObject recipients = CBORObject.NewArray();
// Build a COSE_Recipient object containing the public keys needed for ECDH
CBORObject recipient = CBORObject.NewArray();
CBORObject protectedHeadersRecip = CBORObject.NewMap();
protectedHeadersRecip.Add(HeaderKeys.Algorithm.AsCBOR(), AlgorithmID.ECDH_ES_HKDF_256.AsCBOR());
CBORObject unprotectedHeadersRecip = CBORObject.NewMap();
// This adds the kid too, which is not specified for this Key in the spec
unprotectedHeadersRecip.Add(
HeaderKeys.ECDH_EPK.AsCBOR(),
ephemeralPubKey);
unprotectedHeadersRecip.Add(HeaderKeys.KID.AsCBOR(), keyId);
recipient.Add(protectedHeadersRecip.EncodeToBytes());
recipient.Add(unprotectedHeadersRecip);
recipient.Add(CBORObject.Null); // ciphertext field, nil if no key
encMsg.Add(protectedHeaders.EncodeToBytes());
encMsg.Add(unprotectedHeaders);
encMsg.Add(content);
recipients.Add(recipient);
encMsg.Add(recipients);
return encMsg;
}