summaryrefslogtreecommitdiff
path: root/src/core/crypto_libsodium.c
blob: 85cf537006098f2850d84ef262ba0e11b416f6a8 (plain)
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);
}
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com