1 
2 #include <string.h>
3 
4 #include "crypto_box_curve25519xchacha20poly1305.h"
5 #include "crypto_generichash.h"
6 #include "private/common.h"
7 #include "utils.h"
8 
9 static int
_crypto_box_curve25519xchacha20poly1305_seal_nonce(unsigned char * nonce,const unsigned char * pk1,const unsigned char * pk2)10 _crypto_box_curve25519xchacha20poly1305_seal_nonce(unsigned char *nonce,
11                                                    const unsigned char *pk1,
12                                                    const unsigned char *pk2)
13 {
14     crypto_generichash_state st;
15 
16     crypto_generichash_init(&st, NULL, 0U,
17                             crypto_box_curve25519xchacha20poly1305_NONCEBYTES);
18     crypto_generichash_update(&st, pk1,
19                               crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES);
20     crypto_generichash_update(&st, pk2,
21                               crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES);
22     crypto_generichash_final(&st, nonce,
23                              crypto_box_curve25519xchacha20poly1305_NONCEBYTES);
24 
25     return 0;
26 }
27 
28 int
crypto_box_curve25519xchacha20poly1305_seal(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * pk)29 crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, const unsigned char *m,
30                                             unsigned long long mlen,
31                                             const unsigned char *pk)
32 {
33     unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES];
34     unsigned char epk[crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES];
35     unsigned char esk[crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES];
36     int           ret;
37 
38     if (crypto_box_curve25519xchacha20poly1305_keypair(epk, esk) != 0) {
39         return -1; /* LCOV_EXCL_LINE */
40     }
41     memcpy(c, epk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES);
42     _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, epk, pk);
43     ret = crypto_box_curve25519xchacha20poly1305_easy(
44          c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, m, mlen,
45          nonce, pk, esk);
46     sodium_memzero(esk, sizeof esk);
47     sodium_memzero(epk, sizeof epk);
48     sodium_memzero(nonce, sizeof nonce);
49 
50     return ret;
51 }
52 
53 int
crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char * m,const unsigned char * c,unsigned long long clen,const unsigned char * pk,const unsigned char * sk)54 crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, const unsigned char *c,
55                                                  unsigned long long clen,
56                                                  const unsigned char *pk,
57                                                  const unsigned char *sk)
58 {
59     unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES];
60 
61     if (clen < crypto_box_curve25519xchacha20poly1305_SEALBYTES) {
62         return -1;
63     }
64     _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, c, pk);
65 
66     COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES <
67                     crypto_box_curve25519xchacha20poly1305_SEALBYTES);
68 
69     return crypto_box_curve25519xchacha20poly1305_open_easy(
70          m, c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES,
71          clen - crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES,
72          nonce, c, sk);
73 }
74 
75 size_t
crypto_box_curve25519xchacha20poly1305_sealbytes(void)76 crypto_box_curve25519xchacha20poly1305_sealbytes(void)
77 {
78     return crypto_box_curve25519xchacha20poly1305_SEALBYTES;
79 }
80