internal override void ToHost(Marshaller m) { Algorithm = (TpmAlgId)m.Get(typeof(TpmAlgId), "algorithm"); if (Algorithm == TpmAlgId.None || Algorithm == TpmAlgId.Null) { return; } KeyBits = (ushort)m.Get(typeof(ushort), "keyBits"); Mode = (TpmAlgId)m.Get(typeof(TpmAlgId), "mode"); }
/// <summary> /// Instantiates the object using a TPM generated key pair /// </summary> /// <param name="pub"></param> /// <param name="priv"></param> public RawRsa(TpmPublic pub, TpmPrivate priv) { var m = new Marshaller(priv.buffer); var privSize = m.Get <UInt16>(); // Assert that the private key blob is in plain text Debug.Assert(priv.buffer.Length == privSize + 2); var sens = m.Get <Sensitive>(); Init(pub, sens.sensitive as Tpm2bPrivateKeyRsa); }
private TpmRc GetResultCode(byte[] responseBuf) { var mOut = new Marshaller(responseBuf); // ReSharper disable once UnusedVariable var responseTag = mOut.Get <TpmSt>(); // ReSharper disable once UnusedVariable var responseParamSize = mOut.Get <uint>(); var resultCode = mOut.Get <TpmRc>(); return(resultCode); }
public Sensitive GetSensitive() { TpmPublic fromCspPublic; TpmPrivate fromCspPrivate = Csp.CspToTpm(ExportCspBlob(), out fromCspPublic); var m = new Marshaller(fromCspPrivate.buffer); ushort privSize = m.Get <UInt16>(); if (fromCspPrivate.buffer.Length != privSize + 2) { Globs.Throw("Invalid key blob"); } return(m.Get <Sensitive>()); }
public static T FromTpmRepresentation <T>(byte[] b) { var m = new Marshaller(b); Object obj = m.Get <T>(); return((T)obj); }
internal override void ToHost(Marshaller m) { Algorithm = m.Get <TpmAlgId>(); switch (Algorithm) { case TpmAlgId.None: case TpmAlgId.Null: return; case TpmAlgId.Xor: KeyBits = 0; Mode = m.Get <TpmAlgId>(); break; case TpmAlgId.Aes: KeyBits = m.Get <ushort>(); Mode = m.Get <TpmAlgId>(); break; default: throw new NotImplementedException(); } }
/// <summary> /// Assuming a ushort-prepended array, return the payload (if properly formed). /// </summary> /// <param name="x"></param> /// <returns></returns> static public byte[] Tpm2BToBuffer(byte[] x) { var m = new Marshaller(x); var len = m.Get <ushort>(); if (len != x.Length - 2) { throw new Exception("Ill formed TPM2B"); } var ret = new byte[len]; Array.Copy(x, 2, ret, 0, len); return(ret); }
internal override void ToHost(Marshaller m) { Algorithm = m.Get <TpmAlgId>(); switch (Algorithm) { case TpmAlgId.None: case TpmAlgId.Null: return; case TpmAlgId.Xor: KeyBits = 0; Mode = m.Get <TpmAlgId>(); break; case TpmAlgId.Aes: KeyBits = m.Get <ushort>(); Mode = m.Get <TpmAlgId>(); break; default: Globs.Throw <NotImplementedException>("SymDef.ToHost: Unknown algorithm"); break; } }
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"); }
/// <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; } }
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> /// Assuming a ushort-prepended array, return the payload (if properly formed). /// </summary> /// <param name="x"></param> /// <returns></returns> static public byte[] Tpm2BToBuffer(byte[] x) { var m = new Marshaller(x); var len = m.Get <ushort>(); if (len != x.Length - 2) { Globs.Throw <ArgumentException>("Tpm2BToBuffer: Ill formed TPM2B"); if (x.Length < 2) { return(new byte[0]); } len = (ushort)(x.Length - 2); } var ret = new byte[len]; Array.Copy(x, 2, ret, 0, len); return(ret); }
/// <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> /// 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 }
} // class PrivateKeyBlob // Trailing parameters are used to populate TpmPublic generated for the key from the blob. public static TpmPrivate CspToTpm(byte[] cspPrivateBlob, out TpmPublic tpmPub, TpmAlgId nameAlg = TpmAlgId.Sha1, ObjectAttr keyAttrs = ObjectAttr.Decrypt | ObjectAttr.UserWithAuth, IAsymSchemeUnion scheme = null, SymDefObject symDef = null) { if (scheme == null) { scheme = new NullAsymScheme(); } if (symDef == null) { symDef = new SymDefObject(); } var m = new Marshaller(cspPrivateBlob, DataRepresentation.LittleEndian); var cspPrivate = m.Get <Csp.PrivateKeyBlob>(); var keyAlg = cspPrivate.publicKeyStruc.aiKeyAlg; if (keyAlg != Csp.AlgId.CAlgRsaKeyX && keyAlg != Csp.AlgId.CAlgRsaSign) { Globs.Throw <NotSupportedException>("CSP blobs for keys of type " + keyAlg.ToString("X") + " are not supported"); tpmPub = new TpmPublic(); return(new TpmPrivate()); } var rsaPriv = new Tpm2bPrivateKeyRsa(Globs.ReverseByteOrder(cspPrivate.prime1)); var sens = new Sensitive(new byte[0], new byte[0], rsaPriv); tpmPub = new TpmPublic(nameAlg, keyAttrs, new byte[0], new RsaParms(symDef, scheme, (ushort)cspPrivate.rsaPubKey.bitlen, cspPrivate.rsaPubKey.pubexp), new Tpm2bPublicKeyRsa(Globs.ReverseByteOrder(cspPrivate.modulus))); return(new TpmPrivate(sens.GetTpm2BRepresentation())); }
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(); }
/// <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; } }