public bool CompareTo(params HashDataProvider[] hashDataProviders) { HashProvider hasher = new HashProvider (_hashAlgo); byte[] localHash = hasher.Hash (hashDataProviders); return ByteHelper.CompareByteArrays (_digest, localHash); }
/// <summary> /// Verifies a signature generated on the tpm /// </summary> /// <param name="keyInfo">The key blob loaded into the tpm</param> /// <param name="pubkey">the public key</param> /// <param name="data">data to verify for integrity</param> /// <param name="signature">signature to verify</param> /// <returns></returns> public static bool VerifySignature(TPMKey keyInfo, TPMPubkey pubkey, byte[] data, byte[] signature) { if (keyInfo.AlgorithmParams.SigScheme == TPMSigScheme.TPM_SS_RSASSAPKCS1v15_SHA1) { byte[] localDataDigest = new HashProvider().Hash(new HashByteDataProvider(data)); ISigner signatureVerificator = pubkey.CreateSignatureVerificator(); signatureVerificator.BlockUpdate(data, 0, data.Length); return signatureVerificator.VerifySignature(signature); } else throw new NotSupportedException(string.Format("The signature scheme '{0}' is not supported", keyInfo.AlgorithmParams.SigScheme)); }
protected override TPMCommandResponse InternalProcess() { // Unencrypted authorization values, they need to be XOR-Encrypted with // XOR(auth, SHA-1(OSAP shared secret | session nonce)) // // OSAP_shared_secret = HMAC(key=usage secret of key handle, nonce even osap | nonce odd osap) AuthHandle auth1OSAP = _commandAuthHelper.AssureOSAPSharedSecret(this, AuthSessionNum.Auth1); _usageAuth = _params.GetValueOf<byte[]> ("usage_auth"); _migrationAuth = _params.GetValueOf<byte[]> ("migration_auth"); byte[] xorKey = new HashProvider().Hash( new HashByteDataProvider(auth1OSAP.SharedSecret), new HashByteDataProvider(auth1OSAP.NonceEven)); ByteHelper.XORBytes(_usageAuth, xorKey); ByteHelper.XORBytes(_migrationAuth, xorKey); //Load parent key if not loaded _keyManager.LoadKey(_params.GetValueOf<string>("parent")); TPMBlob requestBlob = new TPMBlob(); requestBlob.WriteCmdHeader(TPMCmdTags.TPM_TAG_RQU_AUTH1_COMMAND, TPMOrdinals.TPM_ORD_CreateWrapKey); //parent key handle gets inserted later, it may be not available now requestBlob.WriteUInt32(0); requestBlob.Write(_usageAuth, 0, 20); requestBlob.Write(_migrationAuth, 0, 20); _tpmKey.WriteToTpmBlob(requestBlob); using(_keyManager.AcquireLock()) { AuthorizeMe(requestBlob); requestBlob.SkipHeader(); if(_params.GetValueOf<string>("parent") == KeyHandle.KEY_SRK) requestBlob.WriteUInt32((uint)TPMKeyHandles.TPM_KH_SRK); else requestBlob.WriteUInt32(_keyManager.IdentifierToHandle(_params.GetValueOf<string>("parent")).Handle); _responseBlob = TransmitMe(requestBlob); } CheckResponseAuthInfo(); _responseBlob.SkipHeader(); TPMKeyCore newKey = new TPMKeyCore(_responseBlob); _responseParameters = new Parameters(); //Build and save the key identifier //The key identifier is the hex-string representation of the hash of the newly created key _responseParameters.AddPrimitiveType("key_identifier", ByteHelper.ByteArrayToHexString( new HashProvider().Hash( new HashByteDataProvider( ByteHelper.SerializeToBytes(newKey) ) ), "")); _responseParameters.AddPrimitiveType("key_data", ByteHelper.SerializeToBytes(newKey)); return new TPMCommandResponse(true, TPMCommandNames.TPM_CMD_CreateWrapKey, _responseParameters); }
protected override TPMCommandResponse InternalProcess() { // Unencrypted authorization values, they need to be XOR-Encrypted with // XOR(auth, SHA-1(OSAP shared secret | session nonce)) // // OSAP_shared_secret = HMAC(key=usage secret of key handle, nonce even osap | nonce odd osap) AuthHandle auth1OSAP = _commandAuthHelper.AssureOSAPSharedSecret(this, AuthSessionNum.Auth1); _encAuth = _params.GetValueOf<byte[]> ("data_auth"); byte[] xorKey = new HashProvider().Hash( new HashByteDataProvider(auth1OSAP.SharedSecret), new HashByteDataProvider(auth1OSAP.NonceEven)); ByteHelper.XORBytes(_encAuth, xorKey); //Load parent key if not loaded _keyManager.LoadKey(_params.GetValueOf<string>("key")); TPMBlob requestBlob = new TPMBlob(); requestBlob.WriteCmdHeader(TPMCmdTags.TPM_TAG_RQU_AUTH1_COMMAND, TPMOrdinals.TPM_ORD_Seal); //key handle gets inserted later, it may be not available now requestBlob.WriteUInt32(0); requestBlob.Write(_encAuth, 0, 20); TPMBlobWriteableHelper.WriteITPMBlobWritableWithUIntSize(requestBlob, _pcrInfo); requestBlob.WriteUInt32((uint)_inData.Length); requestBlob.Write(_inData, 0, _inData.Length); AuthorizeMe(requestBlob); using(_keyManager.AcquireLock()) { requestBlob.SkipHeader(); requestBlob.WriteUInt32(_keyManager.IdentifierToHandle(_params.GetValueOf<string>("key")).Handle); _responseBlob = TransmitMe(requestBlob); } CheckResponseAuthInfo(); _responseBlob.SkipHeader(); TPMStoredDataCore sealedData = TPMStoredDataCore.CreateFromTPMBlob(_responseBlob); Parameters responseParams = new Parameters(); responseParams.AddPrimitiveType("data", ByteHelper.SerializeToBytes(sealedData)); return new TPMCommandResponse(true, TPMCommandNames.TPM_CMD_Seal, responseParams); }
/// <summary> /// Locks the password and calculates the password hash /// </summary> public void Hash() { if (_protectedHash != null) throw new NotSupportedException ("Cannot hash twice"); if(_injectedHash != null) return; _plainPassword.MakeReadOnly (); HashProvider hashProvider = new HashProvider (_hashAlgo); //The array fpr protected memory needs to have multiple size of 16 //int byteArrayLength = // 4 // 4 bytes size of the actual hash value // + hashProvider.HashBitSize/8; //byteArrayLength += byteArrayLength % 16; //byte[] myHashValue = new byte[byteArrayLength]; _currentHashSize = hashProvider.HashBitSize / 8; byte[] myHashValue = new byte[_currentHashSize]; hashProvider.Hash (myHashValue, 0, new HashSecureStringDataProvider (_plainPassword)); //HACK: It's not sure that the converted strings get deleted by the // garbage collector. Use ProtectedMemory as soon as possible _protectedHash = new SecureString (); foreach (byte b in myHashValue) { string hexString = string.Format ("{0:X2}", b); foreach (char c in hexString) _protectedHash.AppendChar (c); } //Writes the size of the ahsh value to the start of the hashvalue array //Array.Copy(BitConverter.GetBytes((int)hashProvider.HashBitSize/8), myHashValue, 4); //Hash value starts at index 4 //hashProvider.Hash(myHashValue, 4, new HashSecureStringDataProvider(_plainPassword)); //ProtectedData.Protect(hashProvider, null, DataProtectionScope. //ProtectedMemory.Protect(myHashValue, MemoryProtectionScope.SameProcess); }
private static void TestHMAC() { ILog log = LogManager.GetLogger("TestHMAC"); HashProvider hash = new HashProvider(); byte[] h1 = hash.Hash( new HashPrimitiveDataProvider((uint)0x3c), new HashPrimitiveDataProvider((ushort)0x00), new HashEnumDataProvider(testenum.test), new HashByteDataProvider(new byte[]{0xb3,0xd5,0xcb, 0x12,0x73, 0x8b, 0xb6, 0xf9, 0x21, 0xa3, 0xda, 0x42,0xe0, 0x18, 0xd1, 0x43, 0xfa, 0x29, 0x7c, 0xa6})); HMACProvider hmac = new HMACProvider( new byte[]{0x75, 0xf0, 0x86, 0x84, 0x78, 0x24, 0xf8, 0x79, 0x39, 0x5a, 0x18, 0x14, 0x1d, 0x19, 0x0c, 0x2f, 0x01, 0x29, 0x0b, 0x05}); byte[] h2 = new byte[20]; for(int i = 0; i<20; i++) h2[i] = 0xa5; byte[] h3 = new byte[]{ 0xb9, 0x73, 0x05, 0xfa, 0xdb, 0xe3, 0x4d, 0xc5, 0x46, 0x65, 0x10, 0x00, 0x0a, 0x55, 0x04, 0x2e, 0x3f, 0xea, 0xbf, 0x27}; byte[] result = hmac.Hash(new HashByteDataProvider(h1), new HashByteDataProvider(h2), new HashByteDataProvider(h3), new HashPrimitiveDataProvider(true)); byte[] expected = new byte[]{ 0x26, 0x7e, 0xca, 0x16, 0xa1, 0x4d, 0x36, 0xe6, 0x72, 0x2e, 0xaa, 0x7f, 0x7b, 0x53, 0x4a, 0xb3, 0xce, 0x8b, 0x2a, 0xaa}; for(int i = 0; i<20; i++) { if(result[i] != expected[i]) Console.WriteLine("FAILED"); } Console.WriteLine("SUCCESS"); }
protected override TPMCommandResponse InternalProcess() { AuthHandle auth1OSAP =_commandAuthHelper.AssureOSAPSharedSecret(this, AuthSessionNum.Auth1); byte[] xorKey = new HashProvider().Hash( new HashByteDataProvider(auth1OSAP.SharedSecret), new HashByteDataProvider(auth1OSAP.NonceEven)); ByteHelper.XORBytes(_secret, xorKey); if(_secret.Length != 20) throw new ArgumentException("secret needs to be 20 bytes long (SHA1 hash)"); if(_label.Length != 4) throw new ArgumentException("Label needs to be 4 bytes long"); using(TPMBlob requestBlob = new TPMBlob()) { requestBlob.WriteCmdHeader(TPMCmdTags.TPM_TAG_RQU_AUTH1_COMMAND, TPMOrdinals.TPM_ORD_CreateCounter); requestBlob.Write(_secret, 0, 20); requestBlob.Write(_label, 0, 4); _responseBlob = AuthorizeMeAndTransmit(requestBlob); } _responseBlob.SkipHeader(); _responseParameters = new Parameters(); _responseParameters.AddPrimitiveType("counter_id", _responseBlob.ReadUInt32()); _responseParameters.AddValue("counter_value", TPMCounterValueCore.CreateFromTPMBlob(_responseBlob)); return new TPMCommandResponse(true, TPMCommandNames.TPM_CMD_CreateCounter, _responseParameters); }
public override void Execute(string[] commandline) { if (commandline.Length < 2) _console.Out.WriteLine ("Error: [local_alias] not specified"); else if (commandline.Length < 3) _console.Out.WriteLine ("Error: [pcr_subcommand] not specified"); ClientContext ctx = _console.GetValue<ClientContext> ("client_context", null); if (ctx == null) { _console.Out.WriteLine ("No active connection was found"); return; } string localAlias = commandline[1]; string pcrCommand = commandline[2]; IDictionary<string, TPMSession> tpmSessions = _console.GetValue<IDictionary<string, TPMSession>> ("tpm_sessions", null); if (tpmSessions == null || tpmSessions.ContainsKey (localAlias) == false) { _console.Out.WriteLine ("Error: Specified local alias was not found"); return; } if (pcrCommand == "report") { uint pcrCount = tpmSessions[localAlias].CapabilityClient.GetPCRCount(); for(uint i = 0; i<pcrCount; i++) _console.Out.WriteLine("#{0}: {1}", i, ByteHelper.ByteArrayToHexString(tpmSessions[localAlias].IntegrityClient.PCRValue(i))); } else if(pcrCommand == "extend") { if(commandline.Length < 4) { _console.Out.WriteLine("Error: 'extend' requires some arguments"); return; } IDictionary<string, string> arguments =_console.SplitArguments(commandline[3], 0); if(arguments.ContainsKey("pcr") == false) { _console.Out.WriteLine("Error: 'extend' requires parameter 'pcr' to be specified"); return; } uint pcr = 0; if(uint.TryParse(arguments["pcr"], out pcr) == false) { _console.Out.WriteLine("Error: 'pcr' could not be parsed, is it a valid pcr specified?"); return; } if(arguments.ContainsKey("data_input") == false) { _console.Out.WriteLine("Error: 'extend' requires parameter 'data_input' to be specified"); return; } TPMSessionSealCommand.DataInputMode dataInput = (TPMSessionSealCommand.DataInputMode)Enum.Parse(typeof(TPMSessionSealCommand.DataInputMode), arguments["data_input"], true); if(dataInput != TPMSessionSealCommand.DataInputMode.Embedded && dataInput != TPMSessionSealCommand.DataInputMode.File) { _console.Out.WriteLine("Error: 'data_input' has an invalid value"); return; } byte[] digest; if(dataInput == TPMSessionSealCommand.DataInputMode.File && arguments.ContainsKey("file") == false) { _console.Out.WriteLine("Error: file-data_input require 'file' argument to be specified"); return; } else if(dataInput == TPMSessionSealCommand.DataInputMode.File) { FileInfo myFile = new FileInfo(arguments["file"]); using(FileStream src = myFile.OpenRead()) { digest = new HashProvider().Hash( new HashStreamDataProvider(src, null, null, false)); } } else if(dataInput == TPMSessionSealCommand.DataInputMode.Embedded) { using(Stream src = new HexFilterStream(new TextReaderStream( new StringReader(commandline[4])))) { digest = new byte[20]; if(src.Length != 20) { throw new ArgumentException("Error: The embedded digest must be 20 bytes long"); } src.Read(digest, 0, 20); } } else throw new ArgumentException(String.Format("data input mode '{0}' is not supported", dataInput)); _console.Out.WriteLine("Doing extension with digest: '{0}'", ByteHelper.ByteArrayToHexString(digest)); byte[] newDigest = tpmSessions[localAlias].IntegrityClient.Extend(pcr, digest); _console.Out.WriteLine("Extension successful, new pcr value: {0}", ByteHelper.ByteArrayToHexString(newDigest)); } else if(pcrCommand == "quote") { if(commandline.Length < 4) { _console.Out.WriteLine("Error: 'quote' requires some arguments"); return; } IDictionary<string, string> arguments =_console.SplitArguments(commandline[3], 0); if(arguments.ContainsKey("pcr") == false) { _console.Out.WriteLine("Error: 'quote' requires parameter 'pcr' to be specified"); return; } if(arguments.ContainsKey("name") == false) { _console.Out.WriteLine("Error: no key name was specified"); return; } ClientKeyHandle keyHandle = tpmSessions[localAlias].KeyClient.GetKeyHandleByFriendlyName(arguments["name"]); TPMPCRSelection pcrSelection = tpmSessions[localAlias].CreateEmptyPCRSelection(); foreach(string pcr in arguments["pcr"].Split('|')) { int pcrValue = int.Parse(pcr); pcrSelection.PcrSelection.SetBit(pcrValue - 1, true); } TPMPCRComposite quoted = keyHandle.SimpleQuote(pcrSelection); IList<int> selectedPCRs = quoted.PCRSelection.SelectedPCRs; for (int i = 0; i < selectedPCRs.Count; i++) { _console.Out.WriteLine("#{0}: {1}", selectedPCRs[i], ByteHelper.ByteArrayToHexString(quoted.PCRValues[i])); } } else _console.Out.WriteLine ("Error, unknown pcr_subcommand '{0}'", commandline[1]); }
protected override TPMCommandResponse InternalProcess() { string key = _params.GetValueOf<string>("key"); _keyManager.LoadKey(key); TPMKey keyInfo = TPMKeyCore.CreateFromBytes(_keyManager.GetKeyBlob(key)); if(keyInfo == null) throw new ArgumentException(string.Format("TPM_Sign could not retrieve keyinfo for key '{0}'", key)); byte[] areaToSign = null; if(keyInfo.AlgorithmParams.SigScheme == TPMSigScheme.TPM_SS_RSASSAPKCS1v15_SHA1) { //Client has hopefully put data in the right format ready for the tpm to process if(_params.IsDefined<byte[]>("areaToSign")) areaToSign = _params.GetValueOf<byte[]>("areaToSign"); //Client just sends data, tpm lib cares about the right, signature dependent, processing else if(_params.IsDefined<byte[]>("data")) { byte[] data = _params.GetValueOf<byte[]>("data"); areaToSign = new HashProvider().Hash(new HashByteDataProvider(data)); } if(areaToSign.Length != 20) { throw new ArgumentException(string.Format("Sig scheme '{0}' expects an area to sign with length 20!", keyInfo.AlgorithmParams.SigScheme)); } } else throw new ArgumentException(string.Format("TPM_Sign has not implemented signature scheme '{0}' for algorithm '{1}'", keyInfo.AlgorithmParams.SigScheme, keyInfo.AlgorithmParams.AlgorithmId)); TPMBlob requestBlob = new TPMBlob(); requestBlob.WriteCmdHeader(TPMCmdTags.TPM_TAG_RQU_AUTH1_COMMAND, TPMOrdinals.TPM_ORD_Sign); //key handle gets inserted later, it may be not available now requestBlob.WriteUInt32(0); requestBlob.WriteUInt32((uint)areaToSign.Length); requestBlob.Write(areaToSign, 0, areaToSign.Length); AuthorizeMe(requestBlob); using (_keyManager.AcquireLock()) { requestBlob.SkipHeader(); requestBlob.WriteUInt32(_keyManager.IdentifierToHandle(key).Handle); _responseBlob = TransmitMe(requestBlob); } CheckResponseAuthInfo(); _responseBlob.SkipHeader(); uint sigSize = _responseBlob.ReadUInt32(); byte[] signature = _responseBlob.ReadBytes((int)sigSize); Parameters responseParams = new Parameters(); responseParams.AddPrimitiveType("sig", signature); return new TPMCommandResponse(true, TPMCommandNames.TPM_CMD_Sign, responseParams); }