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 
17 int
crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char * pk,unsigned char * sk,const unsigned char * seed)18 crypto_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 
31 int
crypto_box_curve25519xchacha20poly1305_keypair(unsigned char * pk,unsigned char * sk)32 crypto_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 
40 int
crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char * k,const unsigned char * pk,const unsigned char * sk)41 crypto_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 
54 int
crypto_box_curve25519xchacha20poly1305_detached_afternm(unsigned char * c,unsigned char * mac,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * k)55 crypto_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 
62 int
crypto_box_curve25519xchacha20poly1305_detached(unsigned char * c,unsigned char * mac,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * pk,const unsigned char * sk)63 crypto_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 
83 int
crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * k)84 crypto_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 
97 int
crypto_box_curve25519xchacha20poly1305_easy(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * n,const unsigned char * pk,const unsigned char * sk)98 crypto_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 
110 int
crypto_box_curve25519xchacha20poly1305_open_detached_afternm(unsigned char * m,const unsigned char * c,const unsigned char * mac,unsigned long long clen,const unsigned char * n,const unsigned char * k)111 crypto_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 
119 int
crypto_box_curve25519xchacha20poly1305_open_detached(unsigned char * m,const unsigned char * c,const unsigned char * mac,unsigned long long clen,const unsigned char * n,const unsigned char * pk,const unsigned char * sk)120 crypto_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 
138 int
crypto_box_curve25519xchacha20poly1305_open_easy_afternm(unsigned char * m,const unsigned char * c,unsigned long long clen,const unsigned char * n,const unsigned char * k)139 crypto_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 
151 int
crypto_box_curve25519xchacha20poly1305_open_easy(unsigned char * m,const unsigned char * c,unsigned long long clen,const unsigned char * n,const unsigned char * pk,const unsigned char * sk)152 crypto_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 
164 size_t
crypto_box_curve25519xchacha20poly1305_seedbytes(void)165 crypto_box_curve25519xchacha20poly1305_seedbytes(void)
166 {
167     return crypto_box_curve25519xchacha20poly1305_SEEDBYTES;
168 }
169 
170 size_t
crypto_box_curve25519xchacha20poly1305_publickeybytes(void)171 crypto_box_curve25519xchacha20poly1305_publickeybytes(void)
172 {
173     return crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES;
174 }
175 
176 size_t
crypto_box_curve25519xchacha20poly1305_secretkeybytes(void)177 crypto_box_curve25519xchacha20poly1305_secretkeybytes(void)
178 {
179     return crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES;
180 }
181 
182 size_t
crypto_box_curve25519xchacha20poly1305_beforenmbytes(void)183 crypto_box_curve25519xchacha20poly1305_beforenmbytes(void)
184 {
185     return crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES;
186 }
187 
188 size_t
crypto_box_curve25519xchacha20poly1305_noncebytes(void)189 crypto_box_curve25519xchacha20poly1305_noncebytes(void)
190 {
191     return crypto_box_curve25519xchacha20poly1305_NONCEBYTES;
192 }
193 
194 size_t
crypto_box_curve25519xchacha20poly1305_macbytes(void)195 crypto_box_curve25519xchacha20poly1305_macbytes(void)
196 {
197     return crypto_box_curve25519xchacha20poly1305_MACBYTES;
198 }
199 
200 size_t
crypto_box_curve25519xchacha20poly1305_messagebytes_max(void)201 crypto_box_curve25519xchacha20poly1305_messagebytes_max(void)
202 {
203     return crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX;
204 }
205