/// <summary>
/// Create activation blobs that can be passed to ActivateCredential. Two
/// blobs are returned:
/// 1) encryptedSecret - symmetric key cfb-symmetrically encrypted with the
/// enveloping key;
/// 2) credentialBlob - the enveloping key OEAP (RSA) encrypted by the public
/// part of this key. This is the return value of this
/// function
/// </summary>
/// <param name="secret"></param>
/// <param name="nameOfKeyToBeActivated"></param>
/// <param name="encryptedSecret"></param>
/// <returns>CredentialBlob (</returns>
public IdObject CreateActivationCredentials(byte[] secret,
byte[] nameOfKeyToBeActivated,
out byte[] encryptedSecret)
{
byte[] seed, encSecret;
switch (type)
{
case TpmAlgId.Rsa:
// The seed should be the same size as the name algorithmdigest
seed = Globs.GetRandomBytes(CryptoLib.DigestSize(nameAlg));
encSecret = EncryptOaep(seed, ActivateEncodingParms);
break;
case TpmAlgId.Ecc:
EccPoint ephemPubPt;
seed = EcdhGetKeyExchangeKey(ActivateEncodingParms, out ephemPubPt);
encSecret = Marshaller.GetTpmRepresentation(ephemPubPt);
break;
default:
Globs.Throw <NotImplementedException>(
"CreateActivationCredentials: Unsupported algorithm");
encryptedSecret = new byte[0];
return(null);
}
Transform(seed);
Transform(encSecret);
var cvx = new Tpm2bDigest(secret);
byte[] cvTpm2B = Marshaller.GetTpmRepresentation(cvx);
Transform(cvTpm2B);
SymDefObject symDef = TssObject.GetSymDef(this);
byte[] symKey = KDF.KDFa(nameAlg, seed, "STORAGE",
nameOfKeyToBeActivated, new byte[0], symDef.KeyBits);
Transform(symKey);
byte[] encIdentity;
// TPM only uses CFB mode in its command implementations
var sd = symDef.Copy();
sd.Mode = TpmAlgId.Cfb;
using (var sym = SymCipher.Create(sd, symKey))
{
// Not all keys specs are supported by SW crypto
if (sym == null)
{
encryptedSecret = null;
return(null);
}
encIdentity = sym.Encrypt(cvTpm2B);
}
Transform(encIdentity);
var hmacKeyBits = CryptoLib.DigestSize(nameAlg);
byte[] hmacKey = KDF.KDFa(nameAlg, seed, "INTEGRITY",
new byte[0], new byte[0], hmacKeyBits * 8);
Transform(hmacKey);
byte[] outerHmac = CryptoLib.Hmac(nameAlg, hmacKey,
Globs.Concatenate(encIdentity, nameOfKeyToBeActivated));
Transform(outerHmac);
encryptedSecret = encSecret;
return(new IdObject(outerHmac, encIdentity));
}