-
Notifications
You must be signed in to change notification settings - Fork 127
/
crypto.c
88 lines (69 loc) · 2.18 KB
/
crypto.c
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
#include <string.h>
#include "sodium.h"
/*
*
* Cipher Text
* +------+-----+----------+
* |NONCE | TAG | DATA |
* +------+-----+----------+
* | 8 | 16 | Variable |
* +------+-----+----------+
*
*/
#define COB crypto_onetimeauth_BYTES // 16U
#define COKB crypto_onetimeauth_KEYBYTES // 32U
#define CSSNB crypto_stream_chacha20_NONCEBYTES // 8U
#define CSSKB crypto_stream_chacha20_KEYBYTES //32U
static uint8_t secret_key[crypto_generichash_BYTES];
static int
chacha20poly1305_encrypt(uint8_t *c, const uint8_t *m, const uint32_t mlen,
const uint8_t *n, const uint8_t *k) {
uint8_t cok[COKB];
crypto_stream_chacha20(cok, COKB, n, k);
crypto_stream_chacha20_xor(c + COB, m, mlen, n, k);
crypto_onetimeauth_poly1305(c, c + COB, mlen, cok);
return 0;
}
static int
chacha20poly1305_decrypt(uint8_t *m, const uint8_t *c, const uint32_t clen,
const uint8_t *n, const uint8_t *k) {
uint8_t cok[COKB];
if (clen < COB) {
return -1;
}
int mlen = clen - COB;
crypto_stream_chacha20(cok, COKB, n, k);
if (crypto_onetimeauth_poly1305_verify(c, c + COB, mlen, cok) == 0) {
return crypto_stream_chacha20_xor(m, c + COB, mlen, n, k);
}
return -1;
}
int
crypto_init(const char *password) {
if (sodium_init() == -1) {
return 1;
}
randombytes_set_implementation(&randombytes_internal_implementation);
randombytes_stir();
return crypto_generichash(secret_key, sizeof secret_key, (uint8_t*)password, strlen(password), NULL, 0);
}
int
crypto_generickey(uint8_t *out, size_t outlen, uint8_t *in, size_t inlen, uint8_t *key, size_t keylen) {
return crypto_generichash(out, outlen, in, inlen, key, keylen);
}
int
crypto_encrypt(uint8_t *c, const uint8_t *m, const uint32_t mlen) {
uint8_t nonce[CSSNB];
randombytes_buf(nonce, CSSNB);
memcpy(c, nonce, CSSNB);
return chacha20poly1305_encrypt(c + CSSNB, m, mlen, nonce, secret_key);
}
int
crypto_decrypt(uint8_t *m, const uint8_t *c, const uint32_t clen) {
uint8_t nonce[CSSNB];
if (clen <= CSSNB + COB) {
return -1;
}
memcpy(nonce, c, CSSNB);
return chacha20poly1305_decrypt(m, c + CSSNB, clen - CSSNB, nonce, secret_key);
}