void UnmarshalArray(Marshaller m, TpmStructMemberInfo memInfo, Type memType, int size) { memInfo.Value = m.GetArray(memType.GetElementType(), size, memInfo.Name); var unmSize = ((Array)memInfo.Value).Length; if (unmSize != size) { var msg = string.Format("Invalid size {0} (instead of " + "{1}) for unmarshaled {2}.{3}", unmSize, size, this.GetType(), memInfo.Name); throw new TssException(msg); } }
internal override void ToHost(Marshaller m) { var id = (TpmAlgId)m.Get(typeof(TpmAlgId), "HashAlg"); if (id == TpmAlgId.Null) { _HashAlg = id; HashData = new byte[0]; return; } _HashAlg = id; int hashLength = CryptoLib.DigestSize(id); HashData = m.GetArray <byte>(hashLength, "HashData"); }
public RawRsa(CryptographicKey key) { IBuffer buf = key.Export(CryptographicPrivateKeyBlobType.BCryptPrivateKey); byte[] blob; CryptographicBuffer.CopyToByteArray(buf, out blob); var m = new Marshaller(blob, DataRepresentation.LittleEndian); var header = m.Get <BCryptRsaKeyBlob>(); E = FromBigEndian(m.GetArray <byte>((int)header.cbPublicExp)); N = FromBigEndian(m.GetArray <byte>((int)header.cbModulus)); P = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); Q = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2)); DP = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); DQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2)); InverseQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); D = FromBigEndian(m.GetArray <byte>((int)header.cbModulus)); }
/// <summary> /// Generates new key pair using OS CSP /// </summary> /// <param name="numBits"></param> /// <param name="publicExponent"></param> public RawRsa(int numBits, int publicExponent = 65537) { AsymmetricKeyAlgorithmProvider prov = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha256); CryptographicKey key = prov.CreateKeyPair((uint)numBits); IBuffer buf = key.Export(CryptographicPrivateKeyBlobType.BCryptPrivateKey); byte[] blob; CryptographicBuffer.CopyToByteArray(buf, out blob); var m = new Marshaller(blob, DataRepresentation.LittleEndian); var header = m.Get <BCryptRsaKeyBlob>(); E = FromBigEndian(m.GetArray <byte>((int)header.cbPublicExp)); N = FromBigEndian(m.GetArray <byte>((int)header.cbModulus)); P = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); Q = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2)); DP = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); DQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2)); InverseQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); D = FromBigEndian(m.GetArray <byte>((int)header.cbModulus)); }
/// <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; } }
/// <summary> /// Generates new key pair using OS CSP /// </summary> /// <param name="numBits"></param> /// <param name="publicExponent"></param> public RawRsa(int numBits, int publicExponent = 65537) { #if TSS_USE_BCRYPT var key = AsymCryptoSystem.Generate(Native.BCRYPT_RSA_ALGORITHM, (uint)numBits); byte[] blob = key.Export(Native.BCRYPT_RSAFULLPRIVATE_BLOB); var m = new Marshaller(blob, DataRepresentation.LittleEndian); var header = m.Get <BCryptRsaKeyBlob>(); E = FromBigEndian(m.GetArray <byte>((int)header.cbPublicExp)); N = FromBigEndian(m.GetArray <byte>((int)header.cbModulus)); P = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); Q = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2)); DP = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); DQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2)); InverseQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1)); D = FromBigEndian(m.GetArray <byte>((int)header.cbModulus)); #else using (var prov = new RSACryptoServiceProvider(numBits)) { Init(prov.ExportParameters(true), numBits); } #endif }
/// <summary> /// Implements unmarshaling logic for most of the TPM object types. /// Can be overridden if a custom unmarshaling logic is required (e.g. /// when unmarshaling of a field depends on other field's value). /// </summary> /// <param name="m"></param> /// <returns></returns> internal virtual void ToHost(Marshaller m) { dbg.Indent(); var members = GetFieldsToMarshal(true); uint mshlStartPos = m.GetGetPos(); for (int i = 0; i < members.Length; ++i) { TpmStructMemberInfo memInfo = members[i]; Type memType = Globs.GetMemberType(memInfo); var wireType = memInfo.WireType; int size = -1; switch (wireType) { case MarshalType.Union: { dbg.Trace("Union " + memType.Name + " with selector " + memInfo.Tag.Value); var elt = UnionElementFromSelector(memType, memInfo.Tag.Value); memInfo.Value = m.Get(elt, memType.Name); break; } case MarshalType.FixedLengthArray: { object arr = Globs.GetMember(memInfo, this); memInfo.Value = m.GetArray(memType.GetElementType(), (arr as Array).Length, memInfo.Name); break; } case MarshalType.SpecialVariableLengthArray: { size = CryptoLib.DigestSize((TpmAlgId)members[i - 1].Value); UnmarshalArray(m, memInfo, memType, size); break; } case MarshalType.VariableLengthArray: { size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName); UnmarshalArray(m, memInfo, memType, size); break; } case MarshalType.EncryptedVariableLengthArray: { uint unmarshaled = m.GetGetPos() - mshlStartPos; size = m.SizedStructLen[m.SizedStructLen.Count - 1] - (int)unmarshaled; UnmarshalArray(m, memInfo, memType, size); break; } case MarshalType.SizedStruct: { size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName); if (size == 0) { break; } m.SizedStructLen.Add(size); memInfo.Value = m.Get(memType, memInfo.Name); int unmSize = Marshaller.GetTpmRepresentation(memInfo.Value).Length; if (unmSize != size) { if (unmSize < size && memType.Name == "TpmPublic") { var pub = memInfo.Value as TpmPublic; var label = Marshaller.GetTpmRepresentation(pub.unique); var context = m.GetArray(typeof(byte), size - unmSize, "") as byte[]; pub.unique = new TpmDerive(label, context); } else { var msg = string.Format("Invalid size {0} (instead of " + "{1}) for unmarshaled {2}.{3}", unmSize, size, this.GetType(), memInfo.Name); throw new TssException(msg); } } m.SizedStructLen.RemoveAt(m.SizedStructLen.Count - 1); break; } default: // Only attempt unmarshaling a field, if it is not sized or // if its size is non-zero. if (memInfo.Tag == null || memInfo.Tag.GetValueAsUInt() != 0) { memInfo.Value = m.Get(memType, memInfo.Name); } break; } dbg.Trace((i + 1) + ": " + wireType + " " + memInfo.Name + (size != -1 ? " of size " + size : "")); // Some property values are dynamically obtained from their linked fields. // Correspondingly, they do not have a setter, so we bypass them here. Debug.Assert(wireType != MarshalType.LengthOfStruct && wireType != MarshalType.ArrayCount); if (wireType != MarshalType.UnionSelector) { Globs.SetMember(memInfo, this, memInfo.Value); } } dbg.Unindent(); }
/// <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; } }
internal virtual void ToHost(Marshaller m) { var members = GetFieldsToMarshal(true); dbg.Indent(); for (int i = 0; i < members.Length; ++i) { TpmStructMemberInfo memInfo = members[i]; Type memType = Globs.GetMemberType(memInfo); var wt = members[i].WireType; switch (wt) { case MarshalType.Union: { dbg.Trace("Union " + memType.Name + " with selector " + memInfo.Tag.Value); memInfo.Value = m.Get(UnionElementFromSelector(memType, memInfo.Tag.Value), memType.Name); break; } case MarshalType.FixedLengthArray: { object arr = Globs.GetMember(memInfo, this); memInfo.Value = m.GetArray(memType.GetElementType(), (arr as Array).Length, memInfo.Name); break; } case MarshalType.VariableLengthArray: { int size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName); memInfo.Value = m.GetArray(memType.GetElementType(), size, memInfo.Name); Debug.Assert(size == ((Array)memInfo.Value).Length); dbg.Trace("Received Array " + memInfo.Name + " of size " + size); break; } case MarshalType.SizedStruct: { int size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName); if (size != 0) { memInfo.Value = m.Get(memType, memInfo.Name); Debug.Assert(size == Marshaller.GetTpmRepresentation(memInfo.Value).Length); } dbg.Trace("Received Struct " + memInfo.Name + " of size " + size); break; } default: // Only attempt unmarshaling a field, if it is not sized or // if its size is non-zero. if (memInfo.Tag == null || memInfo.Tag.GetValueAsUInt() != 0) { memInfo.Value = m.Get(memType, memInfo.Name); } break; } dbg.Trace((i + 1) + ": " + memInfo.Name + " = " + memInfo.Value); // Some property values are dynamically obtained from their linked fields. // Correspondingly, they do not have a setter, so we bypass them here. Debug.Assert(wt != MarshalType.LengthOfStruct && wt != MarshalType.ArrayCount); if (wt != MarshalType.UnionSelector) { Globs.SetMember(memInfo, this, memInfo.Value); } } dbg.Unindent(); }