public void TestHkdkf() { var hkdkf = new HkdfSha512(); var result = hkdkf.DeriveBytes(SharedSecret.Import(HkdfIkm), HkdfSalt, HkdfInfo, 42); Assert.Equal(HkdfOkm, result); }
public static void Properties() { var a = new HkdfSha512(); Assert.True(a.PseudorandomKeySize > 0); Assert.True(a.MaxOutputSize > 0); }
public static void ExtractWithSpanTooLong() { var a = new HkdfSha512(); using (var s = SharedSecret.Import(ReadOnlySpan <byte> .Empty)) { Assert.Throws <ArgumentException>("pseudorandomKey", () => a.Extract(s, ReadOnlySpan <byte> .Empty, new byte[a.PseudorandomKeySize + 1])); } }
public static void ExpandWithCountWithLongPrk() { var a = new HkdfSha512(); var b = a.Expand((s_prkForEmpty + s_prkForEmpty).DecodeHex(), ReadOnlySpan <byte> .Empty, 256); Assert.NotNull(b); Assert.Equal(256, b.Length); }
public static void ExpandWithCountSuccess(int count) { var a = new HkdfSha512(); var expected = s_outputForEmpty.DecodeHex().Substring(0, count); var actual = a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, count); Assert.NotNull(actual); Assert.Equal(expected, actual); Assert.Equal(count, actual.Length); }
public static void ExpandWithMaxCount() { var a = new HkdfSha512(); var expected = s_outputForEmpty.DecodeHex(); var actual = a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, a.MaxOutputSize); Assert.NotNull(actual); Assert.Equal(expected, actual); Assert.Equal(a.MaxOutputSize, actual.Length); }
public static void ExpandWithSpanSuccess(int count) { var a = new HkdfSha512(); var expected = s_outputForEmpty.DecodeHex().Substring(0, count); var actual = new byte[count]; a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, actual); Assert.Equal(expected, actual); }
public static void ExpandWithMaxSpan() { var a = new HkdfSha512(); var expected = s_outputForEmpty.DecodeHex(); var actual = new byte[a.MaxOutputSize]; a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, actual); Assert.Equal(expected, actual); }
public static void ExtractSuccess() { var a = new HkdfSha512(); using (var s = SharedSecret.Import(ReadOnlySpan <byte> .Empty)) { var expected = s_prkForEmpty.DecodeHex(); var actual = a.Extract(s, ReadOnlySpan <byte> .Empty); Assert.Equal(expected, actual); Assert.Equal(a.PseudorandomKeySize, actual.Length); } }
public static void ExtractWithEmptySalt() { const int HashLen = 512 / 8; var a = new HkdfSha512(); using (var s = SharedSecret.Import(ReadOnlySpan <byte> .Empty)) { var expected = a.Extract(s, new byte[HashLen]); var actual = a.Extract(s, ReadOnlySpan <byte> .Empty); Assert.Equal(expected, actual); } }
public static void ExtractWithSpanSuccess() { var a = new HkdfSha512(); using (var s = SharedSecret.Import(ReadOnlySpan <byte> .Empty)) { var expected = s_prkForEmpty.DecodeHex(); var actual = new byte[expected.Length]; a.Extract(s, ReadOnlySpan <byte> .Empty, actual); Assert.Equal(expected, actual); } }
public static void ExtractWithSpanWithEmptySalt() { const int HashLen = 512 / 8; var a = new HkdfSha512(); using (var s = SharedSecret.Import(ReadOnlySpan <byte> .Empty)) { var expected = new byte[a.PseudorandomKeySize]; var actual = new byte[expected.Length]; a.Extract(s, new byte[HashLen], expected); a.Extract(s, ReadOnlySpan <byte> .Empty, actual); Assert.Equal(expected, actual); } }
internal Tlv HandlePairSetupM5Raw(ConnectionSession session, out KeyPair keyPair) { var hdkf = new HkdfSha512(); var accessory = hdkf.DeriveBytes( SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()), Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Salt"), Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Info"), 32); keyPair = KeyGenerator.GenerateNewPair(); var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId); var material = accessory.Concat(serverUsername).Concat(keyPair.PublicKey).ToArray(); var signature = Chaos.NaCl.Ed25519.Sign(material, keyPair.PrivateKey); var encoder = new Tlv(); encoder.AddType(Constants.Identifier, serverUsername); encoder.AddType(Constants.PublicKey, keyPair.PublicKey); encoder.AddType(Constants.Signature, signature); return(encoder); }
public static void ExpandWithSpanTooLarge() { var a = new HkdfSha512(); Assert.Throws <ArgumentException>("bytes", () => a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, new byte[a.MaxOutputSize + 1])); }
static void Main(string[] args) { Channel channel = new Channel("ac.testnet.libra.org:8000", ChannelCredentials.Insecure); var client = new AdmissionControl.AdmissionControl.AdmissionControlClient(channel); HexEncoder hex = new HexEncoder(); SharedSecret sharedSecret = SharedSecret.Import(Encoding.UTF8.GetBytes("newdummy")); HkdfSha512 kdf = new HkdfSha512(); var key = kdf.DeriveKey(sharedSecret, null, null, Ed25519.Ed25519); var sender = key.PublicKey.Export(KeyBlobFormat.RawPublicKey); UInt64 seqNum = 11; string senderHex = hex.EncodeData(Sha3.Sha3256().ComputeHash(sender)); uint amount = 10000000; string reciver = "4ba2555fd146e79e37fda7a2f30dc1b4f3d9228aa48b230dbab0a18d407f2f9b"; RawTransactionLCS rawTr = new RawTransactionLCS() { ExpirationTime = (ulong)DateTimeOffset.UtcNow.AddSeconds(60) .ToUnixTimeSeconds(), GasUnitPrice = 0, MaxGasAmount = 100000, SequenceNumber = seqNum }; rawTr.TransactionPayload = new TransactionPayloadLCS(); rawTr.TransactionPayload.PayloadType = (uint)TransactionPayloadLCSEnum.Script; rawTr.TransactionPayload.Script = new ScriptLCS() { Code = Utilities.PtPTrxBytecode, TransactionArguments = new List <TransactionArgumentLCS>() { new TransactionArgumentLCS() { ArgType = (uint)TransactionArgumentLCSEnum.Address, Address = new AddressLCS(reciver) }, new TransactionArgumentLCS() { ArgType = (uint)TransactionArgumentLCSEnum.U64, U64 = amount } } }; rawTr.Sender = new AddressLCS(senderHex); var bytesTrx = LCSCore.LCSSerialization(rawTr); Types.SignedTransaction signedTx = new Types.SignedTransaction(); var bytesTrxHash = Google.Protobuf.ByteString.CopyFrom(bytesTrx); var seed = Encoding.ASCII.GetBytes(RAWTX_HASH_SALT + LIBRA_HASH_SUFFIX); var seedHash = Sha3.Sha3256().ComputeHash(seed); List <byte> hashInput = new List <byte>(); hashInput.AddRange(seedHash); hashInput.AddRange(bytesTrxHash); var hash = Sha3.Sha3256().ComputeHash(hashInput.ToArray()); SubmitTransactionRequest req = new SubmitTransactionRequest(); req.SignedTxn = new SignedTransaction(); List <byte> retArr = new List <byte>(); retArr = retArr.Concat(bytesTrx).ToList(); retArr = retArr.Concat( LCSCore.LCSSerialization(key.Export(KeyBlobFormat.RawPublicKey))).ToList(); var sig = SignatureAlgorithm.Ed25519.Sign(key, hash); retArr = retArr.Concat(LCSCore.LCSSerialization(sig)).ToList(); req.SignedTxn.SignedTxn = ByteString.CopyFrom(retArr.ToArray()); var result = client.SubmitTransaction( req, new Metadata()); Task.Delay(5000).Wait(); GetTransaction(client, senderHex, seqNum); }
public PairVerifyReturn Post(Tlv parts, HapSession session) { var state = parts.GetTypeAsInt(Constants.State); if (state == 1) { _logger.LogDebug("* Pair Verify Step 1/4"); _logger.LogDebug("* Verify Start Request"); var clientPublicKey = parts.GetType(Constants.PublicKey); byte[] privateKey = new byte[32]; Random random = new Random(); random.NextBytes(privateKey); var publicKey = Curve25519.GetPublicKey(privateKey); var sharedSecret = Curve25519.GetSharedSecret(privateKey, clientPublicKey); var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId); var material = publicKey.Concat(serverUsername).Concat(clientPublicKey).ToArray(); var accessoryLtsk = StringToByteArray(HapControllerServer.HapControllerLtsk); var proof = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk); var hdkf = new HkdfSha512(); var hkdfEncKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Salt"), Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Info"), 32); var encoder = new Tlv(); encoder.AddType(Constants.Identifier, serverUsername); encoder.AddType(Constants.Signature, proof); var plaintext = TlvParser.Serialize(encoder); var zeros = new byte[] { 0, 0, 0, 0 }; var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg02")); var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt( Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], plaintext); var responseTlv = new Tlv(); responseTlv.AddType(Constants.State, 2); responseTlv.AddType(Constants.EncryptedData, encryptedOutput); responseTlv.AddType(Constants.PublicKey, publicKey); // Store the details on the session. // session.ClientPublicKey = clientPublicKey; session.PrivateKey = privateKey; session.PublicKey = publicKey; session.SharedSecret = sharedSecret; session.HkdfPairEncKey = hkdfEncKey; var encSalt = Encoding.UTF8.GetBytes("Control-Salt"); var infoRead = Encoding.UTF8.GetBytes("Control-Read-Encryption-Key"); var infoWrite = Encoding.UTF8.GetBytes("Control-Write-Encryption-Key"); session.AccessoryToControllerKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoRead, 32); session.ControllerToAccessoryKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoWrite, 32); return(new PairVerifyReturn { TlvData = responseTlv, Ok = true, HapSession = session }); } if (state == 3) { _logger.LogDebug("* Pair Verify Step 3/4"); _logger.LogDebug("* Verify Finish Request"); var encryptedData = parts.GetType(Constants.EncryptedData); var zeros = new byte[] { 0, 0, 0, 0 }; var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg03")); var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(Key.Import(AeadAlgorithm.ChaCha20Poly1305, session.HkdfPairEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], encryptedData, out var output); if (!decrypt) { var errorTlv = new Tlv(); errorTlv.AddType(Constants.State, 4); errorTlv.AddType(Constants.Error, ErrorCodes.Authentication); return(new PairVerifyReturn { TlvData = errorTlv, Ok = false }); } var subData = TlvParser.Parse(output); var clientUserName = subData.GetType(Constants.Identifier); var signature = subData.GetType(Constants.Signature); var clientPublicKey = StringToByteArray(HapControllerServer.HapControllerLtpk); var material = session.ClientPublicKey.Concat(clientUserName).Concat(session.PublicKey).ToArray(); session.ClientUsername = Automatica.Core.Driver.Utility.Utils.ByteArrayToString(in clientUserName); if (!Chaos.NaCl.Ed25519.Verify(signature, material, clientPublicKey)) { var errorTlv = new Tlv(); errorTlv.AddType(Constants.State, 4); errorTlv.AddType(Constants.Error, ErrorCodes.Authentication); return(new PairVerifyReturn { TlvData = errorTlv, Ok = false }); } var responseTlv = new Tlv(); responseTlv.AddType(Constants.State, 4); session.IsVerified = true; session.SkipFirstEncryption = true; return(new PairVerifyReturn { Ok = true, TlvData = responseTlv }); } return(null); }
public static void ExpandWithSpanWithPrkTooShort() { var a = new HkdfSha512(); Assert.Throws <ArgumentException>("pseudorandomKey", () => a.Expand(new byte[a.PseudorandomKeySize - 1], ReadOnlySpan <byte> .Empty, new byte[0])); }
public PairSetupReturn Post(Tlv parts) { var customParams = SrpParameters.Create3072 <SHA512>(); var state = parts.GetTypeAsInt(Constants.State); if (state == 1) //srp sign up { var rnd = new Random(); _salt = new byte[16]; rnd.NextBytes(_salt); _saltInt = SrpInteger.FromByteArray(_salt); var srp = new SrpClient(customParams); _privateKey = srp.DerivePrivateKey(_saltInt.ToHex(), Username, _code); _verifier = srp.DeriveVerifier(_privateKey); _server = new SrpServer(customParams); _serverEphemeral = _server.GenerateEphemeral(_verifier); var responseTlv = new Tlv(); responseTlv.AddType(Constants.State, 2); responseTlv.AddType(Constants.PublicKey, StringToByteArray(_serverEphemeral.Public)); responseTlv.AddType(Constants.Salt, _salt); return(new PairSetupReturn { State = 1, TlvData = responseTlv, Ok = true }); } if (state == 3) //srp authenticate { _logger.LogDebug("Pair Setup Step 3/6"); _logger.LogDebug("SRP Verify Request"); var pubKey = parts.GetType(Constants.PublicKey); var proof = parts.GetType(Constants.Proof); var iOsPublicKey = SrpInteger.FromByteArray(pubKey); var iOsProof = SrpInteger.FromByteArray(proof); var responseTlv = new Tlv(); responseTlv.AddType(Constants.State, 4); var ok = true; try { _serverSession = _server.DeriveSession(_serverEphemeral.Secret, iOsPublicKey.ToHex(), _saltInt.ToHex(), Username, _verifier, iOsProof.ToHex()); _logger.LogInformation("Verification was successful. Generating Server Proof (M2)"); responseTlv.AddType(Constants.Proof, StringToByteArray(_serverSession.Proof)); } catch (Exception) { ok = false; _logger.LogError("Verification failed as iOS provided code was incorrect"); responseTlv.AddType(Constants.Error, ErrorCodes.Authentication); } return(new PairSetupReturn { State = 3, Ok = ok, TlvData = responseTlv }); } if (state == 5) { _logger.LogDebug("Pair Setup Step 5/6"); _logger.LogDebug("Exchange Response"); try { var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A var zeros = new byte[] { 0, 0, 0, 0 }; var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05")); var hdkf = new HkdfSha512(); var hkdfEncKey = hdkf.DeriveBytes( SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()), Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"), Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32); var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt( Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], iOsEncryptedData, out var output); var responseTlv = new Tlv(); responseTlv.AddType(Constants.State, 6); if (!decrypt) { responseTlv.AddType(Constants.Error, ErrorCodes.Authentication); return(new PairSetupReturn { State = 5, TlvData = responseTlv, Ok = false }); } var subData = TlvParser.Parse(output); byte[] username = subData.GetType(Constants.Identifier); byte[] ltpk = subData.GetType(Constants.PublicKey); byte[] proof = subData.GetType(Constants.Signature); var okm = hdkf.DeriveBytes( SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()), Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"), Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32); var completeData = okm.Concat(username).Concat(ltpk).ToArray(); if (!SignatureAlgorithm.Ed25519.Verify( PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData, proof)) { var errorTlv = new Tlv(); errorTlv.AddType(Constants.Error, ErrorCodes.Authentication); return(new PairSetupReturn { State = 5, TlvData = errorTlv, Ok = false }); } var accessory = hdkf.DeriveBytes( SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()), Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Salt"), Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Info"), 32); var seed = new byte[32]; RandomNumberGenerator.Create().GetBytes(seed); Chaos.NaCl.Ed25519.KeyPairFromSeed(out var accessoryLtpk, out var accessoryLtsk, seed); var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId); var material = accessory.Concat(serverUsername).Concat(accessoryLtpk).ToArray(); var signature = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk); var encoder = new Tlv(); encoder.AddType(Constants.Identifier, serverUsername); encoder.AddType(Constants.PublicKey, accessoryLtpk); encoder.AddType(Constants.Signature, signature); var plaintext = TlvParser.Serialise(encoder); var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06")); var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt( Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6, new byte[0], plaintext); responseTlv.AddType(Constants.EncryptedData, encryptedOutput); return(new PairSetupReturn { State = 5, TlvData = responseTlv, Ok = true, Ltsk = ByteArrayToString(accessoryLtsk), Ltpk = ByteArrayToString(ltpk) }); } catch (Exception e) { _logger.LogError(e, "Could not exchange request"); throw; } } return(null); }
public static void ExtractWithSpanWithNullSecret() { var a = new HkdfSha512(); Assert.Throws <ArgumentNullException>("sharedSecret", () => a.Extract(null, ReadOnlySpan <byte> .Empty, Span <byte> .Empty)); }
public static void ExpandWithCountTooLarge() { var a = new HkdfSha512(); Assert.Throws <ArgumentOutOfRangeException>("count", () => a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, a.MaxOutputSize + 1)); }
public static void ExpandWithNegativeCount() { var a = new HkdfSha512(); Assert.Throws <ArgumentOutOfRangeException>("count", () => a.Expand(s_prkForEmpty.DecodeHex(), ReadOnlySpan <byte> .Empty, -1)); }
internal PairSetupReturn HandlePairSetupM5(Tlv parts, ConnectionSession session) { _logger.LogDebug("Pair Setup Step 5/5"); _logger.LogDebug("Exchange Response"); try { var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A var zeros = new byte[] { 0, 0, 0, 0 }; var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05")); var hdkf = new HkdfSha512(); var hkdfEncKey = hdkf.DeriveBytes( SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()), Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"), Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32); var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt( Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], iOsEncryptedData, out var output); var responseTlv = new Tlv(); responseTlv.AddType(Constants.State, 6); if (!decrypt) { responseTlv.AddType(Constants.Error, ErrorCodes.Authentication); return(new PairSetupReturn { State = 5, TlvData = responseTlv, Ok = false }); } var subData = TlvParser.Parse(output); byte[] username = subData.GetType(Constants.Identifier); byte[] ltpk = subData.GetType(Constants.PublicKey); byte[] proof = subData.GetType(Constants.Signature); var okm = hdkf.DeriveBytes( SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()), Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"), Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32); var completeData = okm.Concat(username).Concat(ltpk).ToArray(); if (!SignatureAlgorithm.Ed25519.Verify( PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData, proof)) { var errorTlv = new Tlv(); errorTlv.AddType(Constants.Error, ErrorCodes.Authentication); return(new PairSetupReturn { State = 5, TlvData = errorTlv, Ok = false }); } var m5Response = HandlePairSetupM5Raw(session, out var keyPair); var plaintext = TlvParser.Serialize(m5Response); _logger.LogDebug($"Decrypted payload {Automatica.Core.Driver.Utility.Utils.ByteArrayToString(plaintext.AsSpan())}"); var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06")); var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt( Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6, new byte[0], plaintext); responseTlv.AddType(Constants.EncryptedData, encryptedOutput); return(new PairSetupReturn { State = 5, TlvData = responseTlv, Ok = true, Ltsk = ByteArrayToString(keyPair.PrivateKey), Ltpk = ByteArrayToString(ltpk) }); } catch (Exception e) { _logger.LogError(e, $"{e}, Could not exchange request"); throw; } }