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
|
#include "hybbx/types.h"
#include <sodium.h>
#include <stdlib.h>
#include <string.h>
static int sodium_ready;
static int ensure_sodium(void)
{
if (!sodium_ready) {
if (sodium_init() < 0) {
return -1;
}
sodium_ready = 1;
}
return 0;
}
void hybbx_libsodium_chacha_lock(uint8_t *ciphertext, uint8_t tag[16],
const uint8_t key[32], const uint8_t nonce[24],
const uint8_t *aad, size_t aad_len,
const uint8_t *plaintext, size_t plaintext_len)
{
unsigned long long out_len = 0;
uint8_t *packed;
size_t packed_cap;
if (ensure_sodium() != 0) {
return;
}
packed_cap = plaintext_len +
crypto_aead_xchacha20poly1305_ietf_ABYTES;
packed = malloc(packed_cap);
if (packed == NULL) {
return;
}
if (crypto_aead_xchacha20poly1305_ietf_encrypt(
packed, &out_len, plaintext, plaintext_len, aad, aad_len, NULL,
nonce, key) != 0) {
free(packed);
return;
}
if (plaintext_len > 0 && ciphertext != NULL) {
memcpy(ciphertext, packed, plaintext_len);
}
memcpy(tag, packed + plaintext_len,
crypto_aead_xchacha20poly1305_ietf_ABYTES);
free(packed);
}
int hybbx_libsodium_chacha_unlock(uint8_t *plaintext, const uint8_t tag[16],
const uint8_t key[32], const uint8_t nonce[24],
const uint8_t *aad, size_t aad_len,
const uint8_t *ciphertext, size_t ciphertext_len)
{
unsigned long long pt_len = 0;
uint8_t *packed;
size_t packed_len;
int rc;
if (ensure_sodium() != 0) {
return -1;
}
packed_len = ciphertext_len +
crypto_aead_xchacha20poly1305_ietf_ABYTES;
packed = malloc(packed_len);
if (packed == NULL) {
return -1;
}
if (ciphertext_len > 0 && ciphertext != NULL) {
memcpy(packed, ciphertext, ciphertext_len);
}
memcpy(packed + ciphertext_len, tag,
crypto_aead_xchacha20poly1305_ietf_ABYTES);
rc = crypto_aead_xchacha20poly1305_ietf_decrypt(
plaintext, &pt_len, NULL, packed, packed_len, aad, aad_len, nonce,
key);
free(packed);
return rc;
}
void hybbx_libsodium_x25519_public_key(uint8_t public_key[32],
const uint8_t secret_key[32])
{
if (ensure_sodium() != 0) {
return;
}
crypto_scalarmult_base(public_key, secret_key);
}
void hybbx_libsodium_x25519_shared(uint8_t shared[32],
const uint8_t secret_key[32],
const uint8_t peer_public_key[32])
{
if (ensure_sodium() != 0) {
return;
}
crypto_scalarmult(shared, secret_key, peer_public_key);
}
|