xref: /freebsd/sys/contrib/libsodium/src/libsodium/crypto_box/crypto_box_seal.c (revision 3611ec604864a7d4dcc9a3ea898c80eb35eef8a0)
1 
2 #include <string.h>
3 
4 #include "crypto_box.h"
5 #include "crypto_generichash.h"
6 #include "private/common.h"
7 #include "utils.h"
8 
9 static int
_crypto_box_seal_nonce(unsigned char * nonce,const unsigned char * pk1,const unsigned char * pk2)10 _crypto_box_seal_nonce(unsigned char *nonce,
11                        const unsigned char *pk1, const unsigned char *pk2)
12 {
13     crypto_generichash_state st;
14 
15     crypto_generichash_init(&st, NULL, 0U, crypto_box_NONCEBYTES);
16     crypto_generichash_update(&st, pk1, crypto_box_PUBLICKEYBYTES);
17     crypto_generichash_update(&st, pk2, crypto_box_PUBLICKEYBYTES);
18     crypto_generichash_final(&st, nonce, crypto_box_NONCEBYTES);
19 
20     return 0;
21 }
22 
23 int
crypto_box_seal(unsigned char * c,const unsigned char * m,unsigned long long mlen,const unsigned char * pk)24 crypto_box_seal(unsigned char *c, const unsigned char *m,
25                 unsigned long long mlen, const unsigned char *pk)
26 {
27     unsigned char nonce[crypto_box_NONCEBYTES];
28     unsigned char epk[crypto_box_PUBLICKEYBYTES];
29     unsigned char esk[crypto_box_SECRETKEYBYTES];
30     int           ret;
31 
32     if (crypto_box_keypair(epk, esk) != 0) {
33         return -1; /* LCOV_EXCL_LINE */
34     }
35     memcpy(c, epk, crypto_box_PUBLICKEYBYTES);
36     _crypto_box_seal_nonce(nonce, epk, pk);
37     ret = crypto_box_easy(c + crypto_box_PUBLICKEYBYTES, m, mlen,
38                           nonce, pk, esk);
39     sodium_memzero(esk, sizeof esk);
40     sodium_memzero(epk, sizeof epk);
41     sodium_memzero(nonce, sizeof nonce);
42 
43     return ret;
44 }
45 
46 int
crypto_box_seal_open(unsigned char * m,const unsigned char * c,unsigned long long clen,const unsigned char * pk,const unsigned char * sk)47 crypto_box_seal_open(unsigned char *m, const unsigned char *c,
48                      unsigned long long clen,
49                      const unsigned char *pk, const unsigned char *sk)
50 {
51     unsigned char nonce[crypto_box_NONCEBYTES];
52 
53     if (clen < crypto_box_SEALBYTES) {
54         return -1;
55     }
56     _crypto_box_seal_nonce(nonce, c, pk);
57 
58     COMPILER_ASSERT(crypto_box_PUBLICKEYBYTES < crypto_box_SEALBYTES);
59     return crypto_box_open_easy(m, c + crypto_box_PUBLICKEYBYTES,
60                                 clen - crypto_box_PUBLICKEYBYTES,
61                                 nonce, c, sk);
62 }
63 
64 size_t
crypto_box_sealbytes(void)65 crypto_box_sealbytes(void)
66 {
67     return crypto_box_SEALBYTES;
68 }
69