Browse Source

26m2sg

master
Mike 6 months ago
commit
15863ca46b
9 changed files with 941 additions and 0 deletions
  1. +118
    -0
      LICENSE
  2. +23
    -0
      README.md
  3. +124
    -0
      blake2s.l
  4. +275
    -0
      functions.l
  5. +54
    -0
      main.l
  6. +103
    -0
      monocypher_ietf.patch
  7. +5
    -0
      test-all.l
  8. +141
    -0
      test-funcs.l
  9. +98
    -0
      test-phase1.l

+ 118
- 0
LICENSE View File

@@ -0,0 +1,118 @@

CC0 1.0 Universal

Statement of Purpose

The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").

Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.

For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.

1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:

i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;

ii. moral rights retained by the original author(s) and/or performer(s);

iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;

iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;

v. rights protecting the extraction, dissemination, use and reuse of data in
a Work;

vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and

vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.

2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.

3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.

4. Limitations and Disclaimers.

a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.

b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or
other defects, accuracy, or the present or absence of errors, whether or not
discoverable, all to the greatest extent permissible under applicable law.

c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer
disclaims responsibility for obtaining any necessary consents, permissions
or other rights required for any use of the Work.

d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to this
CC0 or use of the Work.

For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>


+ 23
- 0
README.md View File

@@ -0,0 +1,23 @@
Wireguard (IK pattern) from [Noise](https://noiseprotocol.org/) protocol framework on PicoLisp.

Mimics of any script from Wireguard's [distribution.](https://git.zx2c4.com/WireGuard/tree/contrib/external-tests)

### How to repeat:
* PicoLisp installed (64bit only)
* Download Monocypher 2.0.5 and apply patch from repo (patch from author)
* Install as shared library
* test-all.l should pass tests then
* run main.l and tcpdump
* and you will see: two packets are handshake, two packets are send and receive pings, last keepalive
```
16:14:22.715850 IP 10.10.25.204.60495 > 163.172.161.0.12913: UDP, length 148
16:14:22.767553 IP 163.172.161.0.12913 > 10.10.25.204.60495: UDP, length 92
16:14:22.787473 IP 10.10.25.204.60495 > 163.172.161.0.12913: UDP, length 80
16:14:22.837615 IP 163.172.161.0.12913 > 10.10.25.204.60495: UDP, length 80
16:14:22.837830 IP 10.10.25.204.60495 > 163.172.161.0.12913: UDP, length 32
```
* if you see 'OK' then all tests passed.

---

Note: test-phase1.l is minimum required handshake on place.

+ 124
- 0
blake2s.l View File

@@ -0,0 +1,124 @@
# https://bitbucket.org/mihailp/tankfeeder/src/default/crypto/
(setq
*BLAKE2S-IV
(mapcar
hex
(quote
"6A09E667" "BB67AE85"
"3C6EF372" "A54FF53A"
"510E527F" "9B05688C"
"1F83D9AB" "5BE0CD19" ) )
*BLAKE2S-S
(mapcar
'((L) (mapcar inc L) )
(quote
( 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
(14 10 4 8 9 15 13 6 1 12 0 2 11 7 5 3)
(11 8 12 0 5 2 15 13 10 14 3 6 7 1 9 4)
( 7 9 3 1 13 12 11 14 2 6 5 10 4 0 15 8)
( 9 0 5 7 2 4 10 15 14 1 11 12 6 8 3 13)
( 2 12 6 10 0 11 8 3 4 13 7 5 15 14 1 9)
(12 5 1 15 14 13 4 10 0 7 6 3 9 2 8 11)
(13 11 7 14 12 1 3 9 5 0 15 4 8 6 2 10)
( 6 15 14 9 11 3 0 8 12 2 13 7 1 4 10 5)
(10 2 8 4 7 6 1 5 15 11 9 14 3 12 13 0) ) ) )
(de mod32 (N)
(& N `(hex "FFFFFFFF")) )
(de not32 (N)
(x| N `(hex "FFFFFFFF")) )
(de add32 @
(mod32 (pass +)) )
(de ror32 (X C)
(| (>> C X) (mod32 (>> (- C 32) X))) )
(de endian (L) # little
(apply
|
(mapcar >> (0 -8 -16 -24) L) ) )
(de _Gblake2s (A B C D X Y)
(let
(VA (get V A)
VB (get V B)
VC (get V C)
VD (get V D) )
(set
'VA (add32 VA VB X)
'VD (ror32 (x| VD VA) 16)
'VC (add32 VC VD)
'VB (ror32 (x| VB VC) 12)
'VA (add32 VA VB Y)
'VD (ror32 (x| VD VA) 8)
'VC (add32 VC VD)
'VB (ror32 (x| VB VC) 7)
(nth V A) VA
(nth V B) VB
(nth V C) VC
(nth V D) VD ) ) )
(de blake2s (Lst Key Out)
(default Out 32)
(let
(Len (length Lst)
KeyLen (length Key)
H (copy *BLAKE2S-IV)
C 0 )
# Lst
(if Lst
(setq
Lst
(need
(* -64 (/ (+ Len 63) 64))
(copy Lst)
0 ) )
(or Key (setq Lst (need 64 0))) )
# Key
(and
Key
(inc 'Len 64)
(setq Lst
(conc
(need
(* -64 (/ (+ KeyLen 63) 64))
(copy Key)
0 )
Lst ) ) )
(set H
(x| (car H) `(hex "1010000") (>> -8 KeyLen) Out) )
(while Lst
(let
(M
(make
(do 16
(link (endian (cut 4 'Lst))) ) )
V (conc (copy H) (copy *BLAKE2S-IV)) )
(if (< Len 64)
(inc 'C (swap 'Len 0))
(inc 'C 64)
(dec 'Len 64) )
(set
(prog1 (nth V 13) (setq @@ (car @))) (x| @@ (mod32 C))
(prog1 (nth V 14) (setq @@ (car @))) (x| @@ (>> 32 C)) )
(and
(=0 Len)
(set (prog1 (nth V 15) (setq @@ (car @)))
(not32 @@) ) )
(for S *BLAKE2S-S
(let MS (mapcar '((I) (get M I)) S)
(_Gblake2s 1 5 9 13 (++ MS) (++ MS))
(_Gblake2s 2 6 10 14 (++ MS) (++ MS))
(_Gblake2s 3 7 11 15 (++ MS) (++ MS))
(_Gblake2s 4 8 12 16 (++ MS) (++ MS))
(_Gblake2s 1 6 11 16 (++ MS) (++ MS))
(_Gblake2s 2 7 12 13 (++ MS) (++ MS))
(_Gblake2s 3 8 9 14 (++ MS) (++ MS))
(_Gblake2s 4 5 10 15 (++ MS) (++ MS)) ) )
(let (LH (head 8 V) LT (tail 8 V))
(for (L H L)
(set L
(x| (++ L) (++ LH) (++ LT)) ) ) ) ) )
(let C (circ 0 8 16 24)
(head
Out
(make
(for N H
(do 4
(link (& (>> (++ C) N) `(hex "FF"))) ) ) ) ) ) ) )


+ 275
- 0
functions.l View File

@@ -0,0 +1,275 @@
(setq
*CONSTRUCTION
`(mapcar char (chop "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"))
*IDENTIFIER
`(mapcar char (chop "WireGuard v1 zx2c4 Jason@zx2c4.com"))
*LABEL_MAC1
`(mapcar char (chop "mac1----"))
*LABEL_COOKIE
`(mapcar char (chop "cookie--"))
*DEMO_SERVER "demo.wireguard.com"
*DEMO_PORT "12913"
*PF_INET 2
*SOCK_DGRAM 2
*PING_LABEL
`(mapcar char (chop "WireGuard"))
# full ip-icmp packet, stolen
*PING_DATA
(69 0 0 37 0 0 0 0 20 1 143 91 10 189 129 2 10 189 129 1 8 0
27 250 3 153 1 182 87 105 114 101 71 117 97 114 100 0 0 0
0 0 0 0 0 0 0 0 ) )
(def 'prv car)
(def 'pub cadr)
(de dh_generate NIL # already seeded
(make (do 32 (link (rand 0 255)))) )
(de ephemrl-pair NIL # (Priv Pub)
(make (link (dh_generate) (dh_pubkey (car (made))))) )
(de hmac (Key Msg) # blake2s
(let Key (copy Key)
(and
(> (length Key) 64)
(setq Key (blake2s Key)) )
(setq Key (need -64 Key 0))
(blake2s
(conc
(mapcar x| (need 64 `(hex "5C")) Key)
(blake2s (conc (mapcar x| (need 64 `(hex "36")) Key) Msg)) ) ) ) )
(de hash32 (Msg)
(blake2s Msg) )
(de mac (Key Msg)
(blake2s Msg Key 16) )
(de kdf1 (C D)
(hmac (hmac C D) (cons 1)) )
(de kdf2 (C D)
(let Z (hmac C D)
(list
(setq @ (hmac Z (cons 1)))
(hmac Z (append @ (cons 2))) ) ) )
(de kdf3 (C D)
(let Z (hmac C D)
(list
(setq @ (hmac Z (cons 1)))
(setq @ (hmac Z (append @ (cons 2))))
(hmac Z (append @ (cons 3))) ) ) )
(de dh_pubkey (S)
(use P
(native
"libmonocypher.so.2"
"crypto_x25519_public_key"
NIL
'(P (32 B . 32))
(cons NIL (32) S) )
P ) )
(de dh (S P)
(use R
(native
"libmonocypher.so.2"
"crypto_x25519"
'I
'(R (32 B . 32))
(cons NIL (32) S)
(cons NIL (32) P) )
R ) )
(de lock_aead (K N P A)
(let
(AL (length A)
PL (length P)
Mac NIL
CH NIL )
(native
"libmonocypher.so.2"
"crypto_lock_aead"
NIL
'(Mac (16 B . 16))
(if P # for empty plain data
(list 'CH (cons PL 'B PL))
0 )
(cons NIL (32) K)
(cons NIL (12) N)
(cons NIL (cons AL) A)
AL
(cons NIL (cons PL) P)
PL )
(conc CH Mac) ) )
# TODO: check return value, now assume always success
(de unlock_aead (K N C A)
(let
(AL (length A)
CL (- (length C) 16)
P NIL)
(native
"libmonocypher.so.2"
"crypto_unlock_aead"
'I
(if (=0 CL) # for empty crypted
@
(list 'P (cons CL 'B CL)) )
(cons NIL (32) K)
(cons NIL (12) N)
(cons NIL (16) (tail 16 C))
(cons NIL (cons AL) A)
AL
(cons NIL (cons CL) (head CL C))
CL )
P ) )
(de tai64n NIL
(let
(S
(+
4611686018427387914
(-
(+ (* 86400 (date T)) (time T))
(* 86400 (date 1970 1 1)) ) )
N (in '(date "+%N") (read)) ) # for real
(conc (big64 S) (big32 N)) ) )
(de nonce (N)
(conc (need 4 0) (little64 N)) )
(de little32 (N)
(make
(do 4
(link (& N 255))
(setq N (>> 8 N)) ) ) )
(de little64 (N)
(make
(do 8
(link (& N 255))
(setq N (>> 8 N)) ) ) )
(de big32 (N)
(make
(do 4
(yoke (& N 255))
(setq N (>> 8 N)) ) ) )
(de big64 (N)
(make
(do 8
(yoke (& N 255))
(setq N (>> 8 N)) ) ) )
(de socket NIL
(native
"@"
"socket"
'I
*PF_INET
*SOCK_DGRAM
17 # IPPROTO_UDP
) )
(de getaddrinfo (Host Port)
(let (Hints NIL Res NIL)
(setq Hints (native "@" "calloc" 'N 1 48))
(struct Hints 'I (0 . 4) -2 -2) # 0, PF_INET, SOCK_DGRAM
(native "@" "getaddrinfo" NIL Host Port Hints '(Res (8 . N) . 0))
(native "@" "free" NIL Hints)
(struct
Res
'(I I I I I I N N N) ) ) )
(de server (Host Port)
(let R (getaddrinfo Host Port)
(list
(socket)
(get R 7) # ai_addr
(get R 5) # ai_addrlen
) ) )
(de sendto (S B) # without return check
(let BL (length B)
(native
"@"
"sendto"
NIL
(car S)
(cons NIL (cons BL) B)
BL
0
(cadr S)
(caddr S) ) ) )
(de recvfrom (S) # without return check
(let
(Buf NIL
N
(native
"@"
"recvfrom"
'N
(car S)
'(Buf (1024 B . 1024))
1024
0
0
0 ) )
(head N Buf) ) )
(de start-handshake NIL
(make
(link 1 0 0 0)
(chain (little32 28))
(chain (pub *E))
(setq
*C (kdf1 *C (pub *E))
*H (hash32 (append *H (pub *E)))
@ (kdf2 *C (dh (prv *E) *RPub))
*C (car @)
*K (cadr @) )
(chain (setq @ (lock_aead *K (nonce 0) *Pub *H)))
(setq
*H (hash32 (append *H @))
# starting for tai64n
@ (kdf2 *C (dh *Prv *RPub))
*C (car @)
*K (cadr @) )
(chain
(setq @ (lock_aead *K (nonce 0) (tai64n) *H)) )
(setq *H (hash32 (append *H @)))
# mac1 and mac2
(chain (mac (hash32 (append *LABEL_MAC1 *RPub)) (made)))
(chain (need 16 0)) ) )
# full packet
(de fin-handshake (Lst)
(let
(Er (head 32 (nth Lst 13))
Crypted (head 16 (nth Lst 45))
Mac1 (head 16 (nth Lst 61))
Empty T )
(test (2 0 0 0) (head 4 Lst))
# check our index in first byte
(test 28 (get Lst 9))
# check MAC1
(test
Mac1
(mac (hash32 (append *LABEL_MAC1 *Pub)) (head 60 Lst)) )
(setq
*IndexR (head 4 (nth Lst 5))
*C (kdf1 *C Er)
*H (hash32 (append *H Er))
*C (kdf1 *C (dh (prv *E) Er))
*C (kdf1 *C (dh *Prv Er))
@ (kdf3 *C *Pre)
*C (car @)
*K (caddr @)
*H (hash32 (append *H (cadr @)))
Empty (unlock_aead *K (nonce 0) Crypted *H)
*H (hash32 (append *H Crypted)) )
(test NIL Empty) # receive empty payload
(setq # split keys
@ (kdf2 *C)
*Enc (car @)
*Dec (cadr @) ) ) )
(de encryption (D)
(make
(link 4 0 0 0)
(chain
(copy *IndexR)
(little64 *Nsend)
(lock_aead
*Enc
(nonce (swap '*Nsend (+ 1 *Nsend)))
D
NIL ) ) ) )
(de decryption (Lst) # full packet
# header and index's first byte
(test (4 0 0 0 28) (head 5 Lst))
# extra check for synced counter
(test (head 8 (nth Lst 9)) (little64 *Nrecv))
(unlock_aead
*Dec
(nonce (swap '*Nrecv (+ 1 *Nrecv)))
(nth Lst 17)
NIL ) )


+ 54
- 0
main.l View File

@@ -0,0 +1,54 @@
`(== 64 64)
(seed (in "/dev/urandom" (rd 8)))
(load "blake2s.l")
(load "functions.l")

(setq
*Prv # WAmgVYXkbT2bCtdcDwolI88/iVi/aV3/PHcUBTQSYmo=
(88 9 160 85 133 228 109 61 155 10 215 92 15 10 37
35 207 63 137 88 191 105 93 255 60 119 20 5 52 18 98 106 )
*Pub # K5sF9yESrSBsOXPd6TcpKNgqoy1Ik3ZFKl4FolzrRyI=
(43 155 5 247 33 18 173 32 108 57 115 221 233 55 41
40 216 42 163 45 72 147 118 69 42 94 5 162 92 235 71 34 )
*RPub # qRCwZSKInrMAq5sepfCdaCsRJaoLe5jhtzfiw7CjbwM=
(169 16 176 101 34 136 158 179 0 171 155 30 165 240 157
104 43 17 37 170 11 123 152 225 183 55 226 195 176 163 111 3 )
*Pre # FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=
(22 144 178 135 11 61 115 28 22 161 94 49 16 187 95
38 248 201 55 236 208 85 19 200 74 89 81 90 7 168 165 81 )

*E (ephemrl-pair)
*C (hash32 *CONSTRUCTION)
*H (hash32 (append *C *IDENTIFIER))
*H (hash32 (append *H *RPub))
*K NIL
*Nsend 0
*Nrecv 0
*IndexR NIL
*Enc NIL
*Dec NIL
*Srv (server *DEMO_SERVER *DEMO_PORT) )

(sendto *Srv (start-handshake))
(fin-handshake (recvfrom *Srv))
# handshake done, keys splitted.

# send encrypted raw ping packet
(sendto *Srv (encryption *PING_DATA))

# retrieve ping response, decrypt and
# find back 'WireGuard' label inside
(test
*PING_LABEL
(head
(length *PING_LABEL)
(nth (decryption (recvfrom *Srv)) 29) ) )

# send keepalive
(sendto *Srv (encryption))
(test *Nsend 2)
(test *Nrecv 1)

(msg 'OK)
(bye)


+ 103
- 0
monocypher_ietf.patch View File

@@ -0,0 +1,103 @@
--- monocypher.c.orig 2018-02-14 21:36:48.000000000 +0200
+++ monocypher.c 2018-02-21 15:10:32.000000000 +0200
@@ -1780,26 +1780,26 @@
void crypto_lock_aead(u8 mac[16],
u8 *cipher_text,
const u8 key[32],
- const u8 nonce[24],
+ const u8 nonce[12],
const u8 *ad , size_t ad_size,
const u8 *plain_text, size_t text_size)
{
crypto_lock_ctx ctx;
- crypto_lock_init (&ctx, key, nonce);
- crypto_lock_auth_ad(&ctx, ad, ad_size);
- crypto_lock_update (&ctx, cipher_text, plain_text, text_size);
- crypto_lock_final (&ctx, mac);
+ crypto_lock_ietf_init(&ctx, key, nonce);
+ crypto_lock_auth_ad (&ctx, ad, ad_size);
+ crypto_lock_update (&ctx, cipher_text, plain_text, text_size);
+ crypto_lock_final (&ctx, mac);
}
int crypto_unlock_aead(u8 *plain_text,
const u8 key[32],
- const u8 nonce[24],
+ const u8 nonce[12],
const u8 mac[16],
const u8 *ad , size_t ad_size,
const u8 *cipher_text, size_t text_size)
{
crypto_unlock_ctx ctx;
- crypto_unlock_init (&ctx, key, nonce);
+ crypto_unlock_ietf_init (&ctx, key, nonce);
crypto_unlock_auth_ad (&ctx, ad, ad_size);
crypto_unlock_auth_message(&ctx, cipher_text, text_size);
crypto_chacha_ctx chacha_ctx = ctx.chacha; // avoid the wiping...
@@ -1830,3 +1830,29 @@
return crypto_unlock_aead(plain_text, key, nonce, mac, 0, 0,
cipher_text, text_size);
}
+
+void crypto_chacha20_ietf_init(crypto_chacha_ctx *ctx,
+ const uint8_t key[32],
+ const uint8_t nonce[12])
+{
+ crypto_chacha20_init (ctx, key, nonce + 4);
+ crypto_chacha20_set_ctr(ctx,
+ (uint64_t)nonce[0] << 32
+ | (uint64_t)nonce[1] << 40
+ | (uint64_t)nonce[2] << 48
+ | (uint64_t)nonce[3] << 56);
+}
+
+void crypto_lock_ietf_init(crypto_lock_ctx *ctx,
+ const uint8_t key [32],
+ const uint8_t nonce[12]) // 96 bits!
+{
+ u8 auth_key[64]; // "Wasting" the whole Chacha block is faster
+ ctx->ad_phase = 1;
+ ctx->ad_size = 0;
+ ctx->message_size = 0;
+ crypto_chacha20_ietf_init(&ctx->chacha, key, nonce); // IETF!
+ crypto_chacha20_stream(&ctx->chacha, auth_key, 64);
+ crypto_poly1305_init (&ctx->poly , auth_key);
+ WIPE_BUFFER(auth_key);
+}
--- monocypher.h.orig 2018-02-13 22:30:07.000000000 +0200
+++ monocypher.h 2018-02-21 13:09:34.000000000 +0200
@@ -102,12 +102,12 @@
void crypto_lock_aead(uint8_t mac[16],
uint8_t *cipher_text,
const uint8_t key[32],
- const uint8_t nonce[24],
+ const uint8_t nonce[12],
const uint8_t *ad , size_t ad_size,
const uint8_t *plain_text, size_t text_size);
int crypto_unlock_aead(uint8_t *plain_text,
const uint8_t key[32],
- const uint8_t nonce[24],
+ const uint8_t nonce[12],
const uint8_t mac[16],
const uint8_t *ad , size_t ad_size,
const uint8_t *cipher_text, size_t text_size);
@@ -129,6 +129,7 @@
// Incremental interface (decryption)
#define crypto_unlock_init crypto_lock_init
+#define crypto_unlock_ietf_init crypto_lock_ietf_init
#define crypto_unlock_auth_ad crypto_lock_auth_ad
#define crypto_unlock_auth_message crypto_lock_auth_message
void crypto_unlock_update(crypto_unlock_ctx *ctx,
@@ -276,4 +277,11 @@
const uint8_t your_secret_key [32],
const uint8_t their_public_key [32]);
+void crypto_chacha20_ietf_init(crypto_chacha_ctx *ctx,
+ const uint8_t key[32],
+ const uint8_t nonce[12]);
+void crypto_lock_ietf_init(crypto_lock_ctx *ctx,
+ const uint8_t key [32],
+ const uint8_t nonce[12]);
+
#endif // MONOCYPHER_H

+ 5
- 0
test-all.l View File

@@ -0,0 +1,5 @@
`(== 64 64)
(load "test-funcs.l")
(load "test-phase1.l")
(msg 'OK-All)
(bye)

+ 141
- 0
test-funcs.l View File

@@ -0,0 +1,141 @@
`(== 64 64)
(seed (in "/dev/urandom" (rd 8)))
(load "blake2s.l")
(load "functions.l")

(test
(141 73 237 128 248 152 146 128 222 214 165 183 91 40 149 197 213 215 13 72 101 235 33 202 170 41 133 242 25 116 229 29)
(dh_pubkey
(203 107 104 95 173 233 228 248 76 191 139 222 244 239 244 200 3 216 199 225 17 253 137 203 28 184 126 90 150 41 226 0) ) )
(test
(3 119 169 7 227 26 48 237 195 166 139 135 91 113 126 80 60 189 180 25 83 6 60 170 144 135 246 18 248 228 92 87)
(dh
(203 107 104 95 173 233 228 248 76 191 139 222 244 239 244 200 3 216 199 225 17 253 137 203 28 184 126 90 150 41 226 0)
(169 16 176 101 34 136 158 179 0 171 155 30 165 240 157 104 43 17 37 170 11 123 152 225 183 55 226 195 176 163 111 3) ) )
(test
(229 240 113 156 118 145 247 86 191 129 201 1 210 198 211 96 126 162 190 165 219 189 123 63 17 26 152 213 173 233 236 77)
(hmac
(96 226 109 174 243 39 239 192 46 195 53 226 160 37 210 208 22 235 66 6 248 114 119 245 45 56 209 152 139 120 205 54)
(72 231 231 229 122 241 215 233 127 29 96 69 242 145 207 219 15 162 137 130 148 142 70 209 234 51 13 164 110 119 129 14) ) )
(test
(170 146 47 242 84 79 142 158 105 69 108 188 12 48 160 7 126 101 29 25 160 95 41 184 115 119 129 165 114 161 123 178)
(hmac
(153 70 196 58 152 133 47 108 184 57 21 207 164 231 210 232 226 22 87 214 186 3 62 51 138 112 182 89 180 193 224 184)
(83 103 202 233 31 99 239 200 53 226 11 231 219 118 70 228 100 48 224 188 69 208 26 120 154 254 41 35 192 10 204 36) ) )
(let (M (need 255 255) K (need 5 255))
(hmac K M)
(test M (need 255 255))
(test K (need 5 255)) )
(let (M (need 255 255) K (need 255 255))
(hmac K M)
(test M (need 255 255))
(test K (need 255 255)) )
(test
(25 186 65 75 100 131 175 85 176 41 82 25 79 229 251 40 137 69 104)
(lock_aead
(range 0 31)
(need 12 0)
(list 1 2 3)
(list 1 2 3) ) )
(test
(list 1 2 3)
(unlock_aead
(range 0 31)
(need 12 0)
(25 186 65 75 100 131 175 85 176 41 82 25 79 229 251 40 137 69 104)
(list 1 2 3) ) )
# test empty AD for *Enc-*Dec
(test
(111 11 1)
(unlock_aead
(need 32 255)
(need 12 77)
(lock_aead
(need 32 255)
(need 12 77)
(list 111 11 1)
NIL )
NIL ) )
# test empty AD and Plain for *Enc-*Dec
(test
NIL
(unlock_aead
(need 32 255)
(need 12 77)
(lock_aead
(need 32 255)
(need 12 77)
NIL
NIL )
NIL ) )
(do 1024
(let
(P (dh_generate (rand 1 8192))
K (need 32 255)
N (need 12 77)
A (need (rand 1 4096) 255) )
(setq @ (lock_aead K N P A))
(test P (unlock_aead K N @ A)) ) )
(test
(48 15 107 246 211 98 231 65 217 227 172 232 229 158 34 177)
(mac (1 2 3) (11 22 33)) )
(test
(43 240 18 246 125 48 121 117 233 216 101 48 212 150 16 14 79 145 13 105 42 123 228 36 148 210 181 37 184 109 139 93)
(hash32 (11 22 33)) )
(test
(9 123 250 53 159 212 113 160 205 122 27 101 224 194 89 135 231 117 15 134 152 20 141 85 191 223 97 126 252 61 127 123)
(hmac
(96 226 109 174 243 39 239 192 46 195 53 226 160 37 210 208 22 235 66 6 248 114 119 245 45 56 209 152 139 120 205 54)
(45 115 241 28 139 206 207 9 4 151 134 71 194 122 143 105 160 104 228 176 193 164 68 32 231 95 180 138 69 76 211 38) ) )
(let C (1 2 3)
(setq C (kdf1 C (need 6 7)))
(test
(104 211 53 248 136 243 74 213 47 230 238 96 86 2 208 13 17 230 139 226 151 190 109 137 226 234 120 218 246 184 131 157)
C ) )
(let
(C (96 226 109 174 243 39 239 192 46 195 53 226 160 37 210 208 22 235 66 6 248 114 119 245 45 56 209 152 139 120 205 54)
K NIL
D (0 197 93 126 110 173 19 251 91 149 112 91 255 138 50 103 142 222 251 199 232 94 157 192 170 239 239 122 57 228 13 60) )
(setq
@ (kdf2 C D)
C (car @)
K (cadr @) )
(test
(38 209 211 59 116 167 34 230 182 32 217 36 179 40 108 45 250 101 151 185 118 86 16 5 153 171 254 172 32 126 3 123)
C )
(test
(227 135 208 181 15 132 52 205 205 55 93 86 9 223 33 179 224 219 174 139 246 188 63 3 46 240 193 221 131 128 169 126)
K ) )
(let E (ephemrl-pair)
(test
(32 32)
(mapcar length E) ) )
(let
(C (70 214 141 30 59 223 144 92 122 50 252 30 169 76 89 128 110 11 35 59 36 175 210 199 98 130 186 133 116 62 225 193)
K (87 244 112 210 168 70 88 136 182 50 149 202 157 55 22 131 166 73 137 9 162 100 112 75 123 104 108 153 130 14 241 152)
Pre NIL
Data (22 144 178 135 11 61 115 28 22 161 94 49 16 187 95 38 248 201 55 236 208 85 19 200 74 89 81 90 7 168 165 81) )
(setq
@ (kdf3 C Data)
C (car @)
Pre (cadr @)
K (caddr @) )
(test
(250 148 154 144 226 5 29 75 250 110 254 176 95 154 90 104 107 127 221 83 129 211 69 155 119 76 156 180 113 147 76 33)
C )
(test
(29 246 187 72 100 247 102 47 99 251 1 33 78 117 143 251 14 24 206 112 71 251 177 187 75 51 174 0 113 166 9 8)
Pre )
(test
(181 99 125 229 116 94 158 129 147 187 143 146 6 101 167 204 101 202 74 243 105 180 26 70 95 221 210 22 248 214 34 5)
K ) )
(test
(0 0 0 0 21 129 233 125 244 16 34 17)
(nonce 1234567890123456789) )
(test
(0 0 0 0 255 255 231 137 4 35 199 138)
(nonce 9999999999999999999) )
(test (big32 1234567) (flip (little32 1234567)))
(test (flip (big64 12345678901234)) (little64 12345678901234))

(msg 'OK-funcs)

+ 98
- 0
test-phase1.l View File

@@ -0,0 +1,98 @@
`(== 64 64)
(seed (in "/dev/urandom" (rd 8)))
(load "blake2s.l")
(load "functions.l")

# wg genkey | tee privatekey | wg pubkey > publickey
# for both peers
(setq
*Pubi (154 108 43 117 98 96 69 36 205 12 89 138 107 175 219 237 218 223 2 25 78 197 229 42 161 22 45 60 130 106 169 102)
*Privi (232 43 9 6 248 75 27 169 97 126 88 32 208 140 114 173 95 149 255 62 139 2 8 127 54 255 130 168 40 84 17 72)
*Pubr (214 143 204 172 63 57 112 125 125 190 140 169 63 119 171 108 130 46 190 121 99 219 249 142 167 220 168 224 249 168 61 54)
*Privr (248 148 179 185 130 100 196 122 238 78 101 10 230 150 76 244 2 227 25 212 241 42 21 240 122 207 198 61 28 22 35 123)

# initiator
*Ei (ephemrl-pair)
*Ci (hash32 *CONSTRUCTION)
*Hi (hash32 (append *Ci *IDENTIFIER))
*Hi (hash32 (append *Hi *Pubr))
*Empty T
*Ki NIL

# responder
*Er (ephemrl-pair)
*Cr (hash32 *CONSTRUCTION)
*Hr (hash32 (append *Cr *IDENTIFIER))
*Hr (hash32 (append *Hr *Pubr))
*Plain NIL
*Kr NIL)
(de initiator NIL # write e, es, s, ss
(make
(link (pub *Ei))
(setq
*Ci (kdf1 *Ci (pub *Ei))
*Hi (hash32 (append *Hi (pub *Ei)))
@ (kdf2 *Ci (dh (prv *Ei) *Pubr))
*Ci (car @)
*Ki (cadr @) )
(link (setq @ (lock_aead *Ki (nonce 0) *Pubi *Hi)))
(setq *Hi (hash32 (append *Hi @))) ) )
(de initiator2 (Lst) # read e, ee, se
(let (Er (car Lst) Crypted (cadr Lst))
(setq
*Ci (kdf1 *Ci Er)
*Hi (hash32 (append *Hi Er))
*Ci (kdf1 *Ci (dh (prv *Ei) Er))
*Ci (kdf1 *Ci (dh *Privi Er))
@ (kdf3 *Ci (need 32 0)) # zero PSK
*Ci (car @)
*Ki (caddr @)
*Hi (hash32 (append *Hi (cadr @)))
*Empty (unlock_aead *Ki (nonce 0) Crypted *Hi)
*Hi (hash32 (append *Hi Crypted)) ) ) )
(de responder (Lst)
(let (Ei (car Lst) Crypted (cadr Lst))
(make
# read e, es, s, ss
(setq
*Cr (kdf1 *Cr Ei)
*Hr (hash32 (append *Hr Ei))
@ (kdf2 *Cr (dh *Privr Ei))
*Cr (car @)
*Kr (cadr @)
*Plain (unlock_aead *Kr (nonce 0) Crypted *Hr)
*Hr (hash32 (append *Hr Crypted)) )

# between phases values are equal
(test *Ci *Cr)
(test *Ki *Kr)
(test *Hi *Hr)
(test *Pubi *Plain)

# write e, ee, se
(link (pub *Er))
(setq
*Cr (kdf1 *Cr (pub *Er))
*Hr (hash32 (append *Hr (pub *Er)))
*Cr (kdf1 *Cr (dh (prv *Er) Ei))
*Cr (kdf1 *Cr (dh (prv *Er) *Plain))
@ (kdf3 *Cr (need 32 0)) # zero PSK
*Cr (car @)
*Kr (caddr @)
*Hr (hash32 (append *Hr (cadr @))) )
(link (setq @ (lock_aead *Kr (nonce 0) NIL *Hr)))
(setq *Hr (hash32 (append *Hr @))) ) ) )

# full handshake steps
(initiator2
(responder
(initiator) ) )

# after handshake values are equal too
(test NIL *Empty) # empty payload
(test *Hi *Hr)
(test *Ki *Kr)
(test *Ci *Cr)
# ready for split keys

(msg 'OK-phase1)

Loading…
Cancel
Save