/// <summary> /// Create a new asymmetric key based on the parameters in keyParms. The resulting key data is returned in structures /// suitable for incorporation in a TPMT_PUBLIC and TPMS_SENSITIVE /// </summary> /// <param name="keyParms"></param> /// <param name="publicParms"></param> /// <returns></returns> internal static ISensitiveCompositeUnion CreateSensitiveComposite(TpmPublic keyParms, out IPublicIdUnion publicParms) { TpmAlgId keyAlgId = keyParms.type; ISensitiveCompositeUnion newSens; // Create the asymmetric key if (keyAlgId != TpmAlgId.Rsa) { Globs.Throw <ArgumentException>("Algorithm not supported"); } var newKeyPair = new RawRsa((keyParms.parameters as RsaParms).keyBits); // Put the key bits into the required structure envelopes newSens = new Tpm2bPrivateKeyRsa(newKeyPair.Private); publicParms = new Tpm2bPublicKeyRsa(newKeyPair.Public); return(newSens); }
/// <summary> /// Create a new random software key (public and private) matching the parameters in keyParams. /// </summary> /// <param name="keyParams"></param> /// <returns></returns> public AsymCryptoSystem(TpmPublic keyParams) { TpmAlgId keyAlgId = keyParams.type; PublicParms = keyParams.Copy(); switch (keyAlgId) { case TpmAlgId.Rsa: { var rsaParams = keyParams.parameters as RsaParms; AsymmetricKeyAlgorithmProvider RsaProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha256); Key = RsaProvider.CreateKeyPair(rsaParams.keyBits); IBuffer keyBlobBuffer = Key.ExportPublicKey(CryptographicPublicKeyBlobType.BCryptPublicKey); byte[] blob; CryptographicBuffer.CopyToByteArray(keyBlobBuffer, out blob); var m = new Marshaller(blob, DataRepresentation.LittleEndian); var header = m.Get <BCryptRsaKeyBlob>(); var modulus = m.GetArray <byte>((int)header.cbModulus); var pubId = new Tpm2bPublicKeyRsa(modulus); PublicParms.unique = pubId; break; } case TpmAlgId.Ecc: { var eccParms = keyParams.parameters as EccParms; var alg = RawEccKey.GetEccAlg(keyParams); if (alg == null) { Globs.Throw <ArgumentException>("Unknown ECC curve"); return; } AsymmetricKeyAlgorithmProvider EccProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(alg); Key = EccProvider.CreateKeyPair((uint)RawEccKey.GetKeyLength(eccParms.curveID)); break; } default: Globs.Throw <ArgumentException>("Algorithm not supported"); break; } }
CreateSensitiveComposite(TpmPublic pub, ref byte[] keyData, out IPublicIdUnion publicId) { ISensitiveCompositeUnion newSens = null; publicId = null; if (pub.type == TpmAlgId.Rsa) { if (keyData != null) { Globs.Throw <ArgumentException>("Cannot specify key data for an RSA key"); return(null); } var newKeyPair = new RawRsa((pub.parameters as RsaParms).keyBits); // Put the key bits into the required structure envelopes newSens = new Tpm2bPrivateKeyRsa(newKeyPair.Private); publicId = new Tpm2bPublicKeyRsa(newKeyPair.Public); } else if (pub.type == TpmAlgId.Symcipher) { var symDef = (SymDefObject)pub.parameters; if (symDef.Algorithm != TpmAlgId.Aes) { Globs.Throw <ArgumentException>("Unsupported symmetric algorithm"); return(null); } int keySize = (symDef.KeyBits + 7) / 8; if (keyData == null) { keyData = Globs.GetRandomBytes(keySize); } else if (keyData.Length != keySize) { keyData = Globs.CopyData(keyData); } else { Globs.Throw <ArgumentException>("Wrong symmetric key length"); return(null); } newSens = new Tpm2bSymKey(keyData); } else if (pub.type == TpmAlgId.Keyedhash) { var scheme = (pub.parameters as KeyedhashParms).scheme; TpmAlgId hashAlg = scheme is SchemeHash ? (scheme as SchemeHash).hashAlg : scheme is SchemeXor ? (scheme as SchemeXor).hashAlg : pub.nameAlg; var digestSize = CryptoLib.DigestSize(hashAlg); if (keyData == null) { keyData = Globs.GetRandomBytes(digestSize); } else if (keyData.Length <= CryptoLib.BlockSize(hashAlg)) { keyData = Globs.CopyData(keyData); } else { Globs.Throw <ArgumentException>("HMAC key is too big"); return(null); } newSens = new Tpm2bSensitiveData(keyData); } else { Globs.Throw <ArgumentException>("Unsupported key type"); } return(newSens); }
/// <summary> /// Create a new random software key (public and private) matching the parameters in keyParams. /// </summary> /// <param name="keyParams"></param> /// <returns></returns> public AsymCryptoSystem(TpmPublic keyParams) { TpmAlgId keyAlgId = keyParams.type; PublicParms = keyParams.Copy(); switch (keyAlgId) { case TpmAlgId.Rsa: { var rsaParams = keyParams.parameters as RsaParms; #if TSS_USE_BCRYPT Key = Generate(Native.BCRYPT_RSA_ALGORITHM, rsaParams.keyBits); if (Key == UIntPtr.Zero) { Globs.Throw("Failed to generate RSA key"); return; } byte[] blob = Export(Native.BCRYPT_RSAPUBLIC_BLOB); var m = new Marshaller(blob, DataRepresentation.LittleEndian); var header = m.Get <BCryptRsaKeyBlob>(); /*var exponent = */ m.GetArray <byte>((int)header.cbPublicExp); var modulus = m.GetArray <byte>((int)header.cbModulus); #else RsaProvider = new RSACryptoServiceProvider(rsaParams.keyBits); var modulus = RsaProvider.ExportParameters(true).Modulus; #endif var pubId = new Tpm2bPublicKeyRsa(modulus); PublicParms.unique = pubId; break; } #if !__MonoCS__ case TpmAlgId.Ecc: { var eccParms = keyParams.parameters as EccParms; var alg = RawEccKey.GetEccAlg(keyParams); if (alg == null) { Globs.Throw <ArgumentException>("Unknown ECC curve"); return; } #if TSS_USE_BCRYPT Key = Generate(alg, (uint)RawEccKey.GetKeyLength(eccParms.curveID)); #else var keyParmsX = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextExport }; using (CngKey key = CngKey.Create(alg, null, keyParmsX)) { byte[] keyIs = key.Export(CngKeyBlobFormat.EccPublicBlob); CngKey.Import(keyIs, CngKeyBlobFormat.EccPublicBlob); if (keyParams.objectAttributes.HasFlag(ObjectAttr.Sign)) { EcdsaProvider = new ECDsaCng(key); } else { EcDhProvider = new ECDiffieHellmanCng(key); } } #endif // !TSS_USE_BCRYPT && !__MonoCS__ break; } #endif // !__MonoCS__ default: Globs.Throw <ArgumentException>("Algorithm not supported"); break; } }