|
| 1 | + # a0: pointer to packet |
| 2 | + # a1: size of packet |
| 3 | + # a2: pointer to src (output u64) |
| 4 | + # a3: pointer to dst (output u64) |
| 5 | + |
| 6 | +# |
| 7 | +# WireGuard (WG) sessions are established by a handshake which establishes 32bit sender and receiver IDs |
| 8 | +# After the first two handshake messages, packets only contain the receiver ID |
| 9 | +# So, we need to keep a record of the sender/receiver pairs from the handshake |
| 10 | +# Here we use a simple 'hash' table (the 'hash' is really just the 16 LSBits of an ID) to store the pairs |
| 11 | +# Hash collisions aren't really a problem, a session will get dropped and it will just change IDs and restart |
| 12 | +# |
| 13 | + |
| 14 | +# macro to lookup a hash table entry |
| 15 | +.macro LOOKUP addr key |
| 16 | + li t2, 0xFFFF |
| 17 | + and t2, \key, t2 # take 'hash' (lower 16) |
| 18 | + la t3, hash_table # load the address of the hash table |
| 19 | + li t4, 6 # size of an entry (2byte receiver msbs, 4byte sender) |
| 20 | + mul \addr, t4, t2 # get the offset for the hash |
| 21 | + add \addr, \addr, t3# address of the hash table entry |
| 22 | +.endm |
| 23 | + |
| 24 | +start: |
| 25 | + li t0, 12 # All WG packets are more than 12 bytes |
| 26 | + bltu a1, t0, err # error, buffer size < 12 |
| 27 | + |
| 28 | + lbu t0, 0(a0) # load WG packet type |
| 29 | + li t1, 4 |
| 30 | + beq t0, t1, trans # transport message |
| 31 | + li t1, 1 |
| 32 | + beq t0, t1, init # initiation packet |
| 33 | + li t1, 2 |
| 34 | + beq t0, t1, resp # initiation response |
| 35 | + li t1, 3 |
| 36 | + beq t0, t1, cookie # under load - cookie |
| 37 | + j err # error, start bytes invalid |
| 38 | +init: |
| 39 | + lwu t0, 4(a0) # load sender |
| 40 | + li t1, 0x123456789 # bogus receiver - 33 bits |
| 41 | + j success |
| 42 | +resp: |
| 43 | + lwu t0, 4(a0) # load sender |
| 44 | + lwu t1, 8(a0) # load receiver |
| 45 | + LOOKUP t5, t1 # lookup receiver |
| 46 | + srli t2, t1, 16 # get most significant bytes of receiver |
| 47 | + sh t2, 0(t5) # store the receiver msbs |
| 48 | + sd t0, 2(t5) # store the sender |
| 49 | + LOOKUP t5, t0 # lookup sender |
| 50 | + srli t2, t0, 16 # get most significant bytes of sender |
| 51 | + sh t2, 0(t5) # store the sender msbs |
| 52 | + sd t1, 2(t5) # store the receiver |
| 53 | + j success |
| 54 | +cookie: |
| 55 | +trans: |
| 56 | + lwu t1, 4(a0) # load receiver |
| 57 | + LOOKUP t5, t1 # lookup receiver |
| 58 | + lhu t2, 0(t5) # load msbs from table |
| 59 | + srli t3, t1, 16 # get receiver msbs |
| 60 | + bne t2, t3, err # error, 'hash' collision - drop and it'll switch addrs |
| 61 | + lwu t0, 2(t5) # load sender |
| 62 | +success: |
| 63 | + sd t0, 0(a2) # store src to output |
| 64 | + sd t1, 0(a3) # store dst to output |
| 65 | + li a0, 0 # success return 0 |
| 66 | + jr ra |
| 67 | +err: |
| 68 | + li a0, -1 # error return -1 |
| 69 | + jr ra |
| 70 | +hash_table: |
| 71 | + .space 399360, 0 # 64k 6 byte slots |
0 commit comments