Example #1
0
    private static byte[] blake2sSelfTest()
    {
        var inc = Blake2s.CreateIncrementalHasher(blake2sCheck.Length);

        foreach (int diglen in new[] { 16, 20, 28, 32 })
        {
            foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 })
            {
                var msg = getTestSequence(msglen);
                var key = getTestSequence(diglen);

                inc.Update(Blake2s.ComputeHash(diglen, msg));
                inc.Update(Blake2s.ComputeHash(diglen, key, msg));
            }
        }

        return(inc.Finish());
    }
Example #2
0
    private static byte[] blake2sNoAllocSelfTest()
    {
        Span <byte> buff = stackalloc byte[Blake2b.DefaultDigestLength];
        var         inc  = Blake2s.CreateIncrementalHasher(blake2sCheck.Length);

        foreach (int diglen in new[] { 16, 20, 28, 32 })
        {
            foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 })
            {
                var msg = getTestSequence(msglen);
                var key = getTestSequence(diglen);

                Blake2s.ComputeAndWriteHash(diglen, msg, buff);
                inc.Update(buff.Slice(0, diglen));

                Blake2s.ComputeAndWriteHash(diglen, key, msg, buff);
                inc.Update(buff.Slice(0, diglen));
            }
        }

        return(inc.TryFinish(buff, out int len) ? buff.Slice(0, len).ToArray() : Array.Empty <byte>());
    }
        public static void WireguardTest()
        {
            var protocol = new Protocol(
                HandshakePattern.IK,
                CipherFunction.ChaChaPoly,
                HashFunction.Blake2s,
                PatternModifiers.Psk2
                );
            var buffer     = new byte[Protocol.MaxMessageLength];
            var buffer2    = new byte[Protocol.MaxMessageLength];
            int bufferRead = 0;

            using (var hs = protocol.Create(true,
                                            new ReadOnlySpan <byte>(Encoding.UTF8.GetBytes("WireGuard v1 zx2c4 [email protected]")),
                                            OurPrivate,
                                            TheirPublic,
                                            new byte[][] { Preshared }))
            {
                var now    = DateTimeOffset.UtcNow; //replace with Noda.Time?
                var tai64n = new byte[12];
                (4611686018427387914ul + (ulong)now.ToUnixTimeSeconds()).ToBigEndian(tai64n);
                ((uint)(now.Millisecond * 1e6)).ToBigEndian(tai64n, 8);

                var initiationPacket = new List <byte> {
                    1, 0, 0, 0
                };                                                              //type initiation
                initiationPacket.AddRange(((uint)28).ToLittleEndian());         //sender, random 4byte

                var(bytesWritten, _, _) = hs.WriteMessage(tai64n, buffer);
                initiationPacket.AddRange(buffer.Take(bytesWritten));           // should be 24byte, ephemeral, static, timestamp

                var hasher   = Blake2s.CreateIncrementalHasher(32);
                var hashThis = Encoding.UTF8.GetBytes("mac1----").Concat(TheirPublic).ToArray();
                hasher.Update(hashThis);
                var finishedHash = hasher.Finish();
                hasher   = Blake2s.CreateIncrementalHasher(16, finishedHash);
                hashThis = initiationPacket.ToArray();
                hasher.Update(hashThis);

                finishedHash = hasher.Finish();
                initiationPacket.AddRange(finishedHash);                        //mac1
                initiationPacket.AddRange(Enumerable.Repeat((byte)0, 16));      //mac2 = zeros if no cookie last received


                var socket         = new DatagramSocket();
                var responsePacket = new TaskCompletionSource <int>();
                var autoResetEvent = new AutoResetEvent(false);
                socket.MessageReceived += (sender, args) =>
                {
                    bufferRead = args.GetDataStream().AsStreamForRead().Read(buffer);
                    autoResetEvent.Set();
                };
                socket.ConnectAsync(new HostName("demo.wireguard.com"), "12913").AsTask().Wait();
                var streamWriter = new BinaryWriter(socket.OutputStream.AsStreamForWrite());
                streamWriter.Write(initiationPacket.ToArray());
                streamWriter.Flush();

                var successful = autoResetEvent.WaitOne(5000);
                if (!successful)
                {
                    return;
                }

                if (buffer[0] != 2)   //type init response
                {
                    return;           //"response packet type wrong: want %d, got %d"
                }
                if (bufferRead != 92) //always this length! for type=2
                {
                    return;           //"response packet too short: want %d, got %d"
                }
                if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0)
                {
                    return; //"response packet has non-zero reserved fields"
                }
                var theirIndex = buffer.LittleEndianToUInt32(4);
                var ourIndex   = buffer.LittleEndianToUInt32(8);
                if (ourIndex != 28)
                {
                    return; //log.Fatalf("response packet index wrong: want %d, got %d", 28, ourIndex)
                }
                var span = new Span <byte>(buffer);
                var(bytesRead, handshakeHash, transport) = hs.ReadMessage(span.Slice(12, 48),
                                                                          span.Slice(100)); //write on same buffer behind the received package (which
                if (bytesRead != 0)
                {
                    return; //"unexpected payload: %x"
                }
                var icmpHeader = new IcmpHeader()
                {
                    Type = 8, Id = 921, Sequence = 438
                };
                var pingMessage = icmpHeader.GetProtocolPacketBytes(Encoding.UTF8.GetBytes("WireGuard"));
                var pingHeader  = new Ipv4Header()
                {
                    Version            = 4, Length = 20, TotalLength = (ushort)(20 + pingMessage.Length),
                    Protocol           = 1, Ttl = 20,
                    SourceAddress      = new IPAddress(new byte[] { 10, 189, 129, 2 }),
                    DestinationAddress = new IPAddress(new byte[] { 10, 189, 129, 1 })
                }.GetProtocolPacketBytes(new byte[0]);


                span[0] = 4;
                span.Slice(1, 3).Assign((byte)0);
                theirIndex.ToLittleEndian(buffer, 4);
                0L.ToLittleEndian(buffer, 8);                                                        //this is the counter, little endian u64
                bytesWritten = transport.WriteMessage(
                    pingHeader.Concat(pingMessage).Concat(Enumerable.Repeat((byte)0, 11)).ToArray(), //pad message with 0 to make mod 16=0
                    span.Slice(16));

                //using (var streamWriter = new BinaryWriter(socket.OutputStream.AsStreamForWrite()))
                streamWriter.Write(span.Slice(0, 16 + bytesWritten).ToArray());
                streamWriter.Flush();
                successful = autoResetEvent.WaitOne(5000);
                if (!successful)
                {
                    return;
                }

                if (buffer[0] != 4)
                {
                    return;//"response packet type wrong: want %d, got %d"
                }
                if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0)
                {
                    return; //"response packet has non-zero reserved fields"
                }
                var replyPacket = buffer2.AsSpan(0, transport.ReadMessage(span.Slice(16, bufferRead - 16), buffer2));
                if (replyPacket.Length != 48)
                {
                    return;
                }

                var replyHeaderLen     = ((int)(replyPacket[0] & 0x0f)) << 2;
                var replyLen           = buffer2.BigEndianToUInt16(2);
                var our_index_received = buffer.LittleEndianToUInt32(4);
                if (our_index_received != 28)
                {
                    return;
                }
                var nonce = buffer2.LittleEndianToUInt64(8);
                //if (nonce != 0)//not parsed correctly?
                //    return;
                var replyMessage = IcmpHeader.Create(buffer2.AsSpan(replyHeaderLen, replyLen - replyHeaderLen).ToArray(), ref bytesRead);
                if (replyMessage.Type != 0 || replyMessage.Code != 0)
                {
                    return;
                }
                if (replyMessage.Id != 921 || replyMessage.Sequence != 438)
                {
                    return;
                }
                var replyPayload = Encoding.UTF8.GetString(buffer2.AsSpan(replyLen - replyHeaderLen + bytesRead, replyHeaderLen - bytesRead));
                if (replyPayload != "WireGuard") //trim necessary?
                {
                    return;
                }
            }
        }
    public void KatBlake2sKeyed(KatEntry ka)
    {
        var hash = compute(Blake2s.CreateIncrementalHasher(ka.Key), ka.Data);

        Assert.True(hash.SequenceEqual(ka.Digest));
    }