1
2#include <limits.h>
3#include <stdint.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "core.h"
8#include "crypto_box_curve25519xchacha20poly1305.h"
9#include "crypto_core_hchacha20.h"
10#include "crypto_hash_sha512.h"
11#include "crypto_scalarmult_curve25519.h"
12#include "crypto_secretbox_xchacha20poly1305.h"
13#include "private/common.h"
14#include "randombytes.h"
15#include "utils.h"
16
17int
18crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk,
19                                                    unsigned char *sk,
20                                                    const unsigned char *seed)
21{
22    unsigned char hash[64];
23
24    crypto_hash_sha512(hash, seed, 32);
25    memcpy(sk, hash, 32);
26    sodium_memzero(hash, sizeof hash);
27
28    return crypto_scalarmult_curve25519_base(pk, sk);
29}
30
31int
32crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk,
33                                               unsigned char *sk)
34{
35    randombytes_buf(sk, 32);
36
37    return crypto_scalarmult_curve25519_base(pk, sk);
38}
39
40int
41crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k,
42                                                const unsigned char *pk,
43                                                const unsigned char *sk)
44{
45    static const unsigned char zero[16] = { 0 };
46    unsigned char s[32];
47
48    if (crypto_scalarmult_curve25519(s, sk, pk) != 0) {
49        return -1;
50    }
51    return crypto_core_hchacha20(k, zero, s, NULL);
52}
53
54int
55crypto_box_curve25519xchacha20poly1305_detached_afternm(
56    unsigned char *c, unsigned char *mac, const unsigned char *m,
57    unsigned long long mlen, const unsigned char *n, const unsigned char *k)
58{
59    return crypto_secretbox_xchacha20poly1305_detached(c, mac, m, mlen, n, k);
60}
61
62int
63crypto_box_curve25519xchacha20poly1305_detached(
64    unsigned char *c, unsigned char *mac, const unsigned char *m,
65    unsigned long long mlen, const unsigned char *n, const unsigned char *pk,
66    const unsigned char *sk)
67{
68    unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES];
69    int           ret;
70
71    COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES >=
72                    crypto_secretbox_xchacha20poly1305_KEYBYTES);
73    if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) {
74        return -1;
75    }
76    ret = crypto_box_curve25519xchacha20poly1305_detached_afternm(c, mac, m,
77                                                                  mlen, n, k);
78    sodium_memzero(k, sizeof k);
79
80    return ret;
81}
82
83int
84crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c,
85                                                    const unsigned char *m,
86                                                    unsigned long long mlen,
87                                                    const unsigned char *n,
88                                                    const unsigned char *k)
89{
90    if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) {
91        sodium_misuse();
92    }
93    return crypto_box_curve25519xchacha20poly1305_detached_afternm(
94        c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, k);
95}
96
97int
98crypto_box_curve25519xchacha20poly1305_easy(
99    unsigned char *c, const unsigned char *m, unsigned long long mlen,
100    const unsigned char *n, const unsigned char *pk, const unsigned char *sk)
101{
102    if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) {
103        sodium_misuse();
104    }
105    return crypto_box_curve25519xchacha20poly1305_detached(
106        c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, pk,
107        sk);
108}
109
110int
111crypto_box_curve25519xchacha20poly1305_open_detached_afternm(
112    unsigned char *m, const unsigned char *c, const unsigned char *mac,
113    unsigned long long clen, const unsigned char *n, const unsigned char *k)
114{
115    return crypto_secretbox_xchacha20poly1305_open_detached(m, c, mac, clen, n,
116                                                            k);
117}
118
119int
120crypto_box_curve25519xchacha20poly1305_open_detached(
121    unsigned char *m, const unsigned char *c, const unsigned char *mac,
122    unsigned long long clen, const unsigned char *n, const unsigned char *pk,
123    const unsigned char *sk)
124{
125    unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES];
126    int           ret;
127
128    if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) {
129        return -1;
130    }
131    ret = crypto_box_curve25519xchacha20poly1305_open_detached_afternm(
132        m, c, mac, clen, n, k);
133    sodium_memzero(k, sizeof k);
134
135    return ret;
136}
137
138int
139crypto_box_curve25519xchacha20poly1305_open_easy_afternm(
140    unsigned char *m, const unsigned char *c, unsigned long long clen,
141    const unsigned char *n, const unsigned char *k)
142{
143    if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) {
144        return -1;
145    }
146    return crypto_box_curve25519xchacha20poly1305_open_detached_afternm(
147        m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c,
148        clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, k);
149}
150
151int
152crypto_box_curve25519xchacha20poly1305_open_easy(
153    unsigned char *m, const unsigned char *c, unsigned long long clen,
154    const unsigned char *n, const unsigned char *pk, const unsigned char *sk)
155{
156    if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) {
157        return -1;
158    }
159    return crypto_box_curve25519xchacha20poly1305_open_detached(
160        m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c,
161        clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, pk, sk);
162}
163
164size_t
165crypto_box_curve25519xchacha20poly1305_seedbytes(void)
166{
167    return crypto_box_curve25519xchacha20poly1305_SEEDBYTES;
168}
169
170size_t
171crypto_box_curve25519xchacha20poly1305_publickeybytes(void)
172{
173    return crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES;
174}
175
176size_t
177crypto_box_curve25519xchacha20poly1305_secretkeybytes(void)
178{
179    return crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES;
180}
181
182size_t
183crypto_box_curve25519xchacha20poly1305_beforenmbytes(void)
184{
185    return crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES;
186}
187
188size_t
189crypto_box_curve25519xchacha20poly1305_noncebytes(void)
190{
191    return crypto_box_curve25519xchacha20poly1305_NONCEBYTES;
192}
193
194size_t
195crypto_box_curve25519xchacha20poly1305_macbytes(void)
196{
197    return crypto_box_curve25519xchacha20poly1305_MACBYTES;
198}
199
200size_t
201crypto_box_curve25519xchacha20poly1305_messagebytes_max(void)
202{
203    return crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX;
204}
205