-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbox-stream.c
More file actions
145 lines (121 loc) · 3.66 KB
/
box-stream.c
File metadata and controls
145 lines (121 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "box-stream.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <arpa/inet.h>
#include <sodium.h>
static uint8_t zeros[sizeof(uint16_t) + crypto_secretbox_MACBYTES];
// wrapping in-place increment of a nonce
static void nonce_inc(uint8_t *nonce)
{
uint8_t i = crypto_secretbox_NONCEBYTES - 1;
while (i != UINT8_MAX) {
nonce[i] += 1;
if (nonce[i] == 0) {
i--;
} else {
break;
}
}
}
// wrapping in-place decrement of a nonce
static void nonce_dec(uint8_t *nonce)
{
uint8_t i = crypto_secretbox_NONCEBYTES - 1;
while (i != UINT8_MAX) {
nonce[i] -= 1;
if (nonce[i] == UINT8_MAX) {
i--;
} else {
break;
}
}
}
// indices into an encrypted packet
#define PACKET_LEN crypto_secretbox_MACBYTES
#define PACKET_MAC PACKET_LEN + sizeof(uint16_t)
#define PACKET_CONTENT PACKET_MAC + crypto_secretbox_MACBYTES
void bs_encrypt_packet(
uint8_t *out,
const uint8_t *plain_packet,
uint16_t packet_len,
const uint8_t encryption_key[crypto_secretbox_KEYBYTES],
uint8_t nonce[crypto_secretbox_NONCEBYTES]
)
{
nonce_inc(nonce);
crypto_secretbox_easy(out + PACKET_MAC, plain_packet, packet_len, nonce, encryption_key);
uint16_t network_packet_len = htons(packet_len);
memcpy(out + PACKET_LEN, &network_packet_len, sizeof(network_packet_len));
nonce_dec(nonce);
crypto_secretbox_easy(out, out + PACKET_LEN, sizeof(uint16_t) + crypto_secretbox_MACBYTES, nonce, encryption_key);
nonce_inc(nonce);
nonce_inc(nonce);
}
void bs_final_header(
uint8_t out[BS_CYPHER_HEADER_SIZE],
const uint8_t encryption_key[crypto_secretbox_KEYBYTES],
const uint8_t nonce[crypto_secretbox_NONCEBYTES]
)
{
crypto_secretbox_easy(out, zeros, sizeof(zeros), nonce, encryption_key);
}
bool bs_is_final_header(const BS_Plain_Header *plain_header)
{
return memcmp(plain_header, zeros, sizeof(uint16_t) + crypto_secretbox_MACBYTES) == 0;
}
bool bs_decrypt_header(
BS_Plain_Header *plain_header,
const uint8_t cypher_header[BS_CYPHER_HEADER_SIZE],
const uint8_t decryption_key[crypto_secretbox_KEYBYTES],
uint8_t nonce[crypto_secretbox_NONCEBYTES]
)
{
if (crypto_secretbox_open_easy((uint8_t *)plain_header, cypher_header, BS_CYPHER_HEADER_SIZE, nonce, decryption_key) == -1) {
return false;
}
plain_header->packet_len = ntohs(*(uint16_t *)plain_header);
return true;
}
bool bs_decrypt_header_inplace(
uint8_t cypher_header[BS_CYPHER_HEADER_SIZE],
const uint8_t decryption_key[crypto_secretbox_KEYBYTES],
uint8_t nonce[crypto_secretbox_NONCEBYTES]
)
{
if (crypto_secretbox_open_easy(cypher_header, cypher_header, BS_CYPHER_HEADER_SIZE, nonce, decryption_key) == -1) {
return false;
}
BS_Plain_Header *plain_header = (BS_Plain_Header*) cypher_header;
plain_header->packet_len = ntohs(*(uint16_t *)cypher_header);
return true;
}
bool bs_decrypt_packet(
uint8_t *out,
const uint8_t *cypher_packet,
const BS_Plain_Header *plain_header,
const uint8_t decryption_key[crypto_secretbox_KEYBYTES],
uint8_t nonce[crypto_secretbox_NONCEBYTES]
)
{
nonce_inc(nonce);
if (crypto_secretbox_open_detached(out, cypher_packet, plain_header->packet_mac, plain_header->packet_len, nonce, decryption_key) == -1) {
return false;
}
nonce_inc(nonce);
return true;
}
bool bs_decrypt_packet_inplace(
uint8_t *cypher_packet,
const BS_Plain_Header *plain_header,
const uint8_t decryption_key[crypto_secretbox_KEYBYTES],
uint8_t nonce[crypto_secretbox_NONCEBYTES]
)
{
nonce_inc(nonce);
if (crypto_secretbox_open_detached(cypher_packet, cypher_packet, plain_header->packet_mac, plain_header->packet_len, nonce, decryption_key) == -1) {
return false;
}
nonce_inc(nonce);
return true;
}