1
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <limits.h>
5 #include <string.h>
6
7 #include "core.h"
8 #include "crypto_aead_xchacha20poly1305.h"
9 #include "crypto_aead_chacha20poly1305.h"
10 #include "crypto_core_hchacha20.h"
11 #include "randombytes.h"
12 #include "utils.h"
13
14 #include "private/common.h"
15
16 int
crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char * c,unsigned char * mac,unsigned long long * maclen_p,const unsigned char * m,unsigned long long mlen,const unsigned char * ad,unsigned long long adlen,const unsigned char * nsec,const unsigned char * npub,const unsigned char * k)17 crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
18 unsigned char *mac,
19 unsigned long long *maclen_p,
20 const unsigned char *m,
21 unsigned long long mlen,
22 const unsigned char *ad,
23 unsigned long long adlen,
24 const unsigned char *nsec,
25 const unsigned char *npub,
26 const unsigned char *k)
27 {
28 unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
29 unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 };
30 int ret;
31
32 crypto_core_hchacha20(k2, npub, k, NULL);
33 memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES,
34 crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4);
35 ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached
36 (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub2, k2);
37 sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES);
38
39 return ret;
40 }
41
42 int
crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char * c,unsigned long long * clen_p,const unsigned char * m,unsigned long long mlen,const unsigned char * ad,unsigned long long adlen,const unsigned char * nsec,const unsigned char * npub,const unsigned char * k)43 crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c,
44 unsigned long long *clen_p,
45 const unsigned char *m,
46 unsigned long long mlen,
47 const unsigned char *ad,
48 unsigned long long adlen,
49 const unsigned char *nsec,
50 const unsigned char *npub,
51 const unsigned char *k)
52 {
53 unsigned long long clen = 0ULL;
54 int ret;
55
56 if (mlen > crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX) {
57 sodium_misuse();
58 }
59 ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached
60 (c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k);
61 if (clen_p != NULL) {
62 if (ret == 0) {
63 clen = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES;
64 }
65 *clen_p = clen;
66 }
67 return ret;
68 }
69
70 int
crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char * m,unsigned char * nsec,const unsigned char * c,unsigned long long clen,const unsigned char * mac,const unsigned char * ad,unsigned long long adlen,const unsigned char * npub,const unsigned char * k)71 crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
72 unsigned char *nsec,
73 const unsigned char *c,
74 unsigned long long clen,
75 const unsigned char *mac,
76 const unsigned char *ad,
77 unsigned long long adlen,
78 const unsigned char *npub,
79 const unsigned char *k)
80 {
81 unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
82 unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 };
83 int ret;
84
85 crypto_core_hchacha20(k2, npub, k, NULL);
86 memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES,
87 crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4);
88 ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached
89 (m, nsec, c, clen, mac, ad, adlen, npub2, k2);
90 sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES);
91
92 return ret;
93
94 }
95
96 int
crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char * m,unsigned long long * mlen_p,unsigned char * nsec,const unsigned char * c,unsigned long long clen,const unsigned char * ad,unsigned long long adlen,const unsigned char * npub,const unsigned char * k)97 crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m,
98 unsigned long long *mlen_p,
99 unsigned char *nsec,
100 const unsigned char *c,
101 unsigned long long clen,
102 const unsigned char *ad,
103 unsigned long long adlen,
104 const unsigned char *npub,
105 const unsigned char *k)
106 {
107 unsigned long long mlen = 0ULL;
108 int ret = -1;
109
110 if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) {
111 ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached
112 (m, nsec,
113 c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES,
114 c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES,
115 ad, adlen, npub, k);
116 }
117 if (mlen_p != NULL) {
118 if (ret == 0) {
119 mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES;
120 }
121 *mlen_p = mlen;
122 }
123 return ret;
124 }
125
126 size_t
crypto_aead_xchacha20poly1305_ietf_keybytes(void)127 crypto_aead_xchacha20poly1305_ietf_keybytes(void)
128 {
129 return crypto_aead_xchacha20poly1305_ietf_KEYBYTES;
130 }
131
132 size_t
crypto_aead_xchacha20poly1305_ietf_npubbytes(void)133 crypto_aead_xchacha20poly1305_ietf_npubbytes(void)
134 {
135 return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES;
136 }
137
138 size_t
crypto_aead_xchacha20poly1305_ietf_nsecbytes(void)139 crypto_aead_xchacha20poly1305_ietf_nsecbytes(void)
140 {
141 return crypto_aead_xchacha20poly1305_ietf_NSECBYTES;
142 }
143
144 size_t
crypto_aead_xchacha20poly1305_ietf_abytes(void)145 crypto_aead_xchacha20poly1305_ietf_abytes(void)
146 {
147 return crypto_aead_xchacha20poly1305_ietf_ABYTES;
148 }
149
150 size_t
crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void)151 crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void)
152 {
153 return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX;
154 }
155
156 void
crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES])157 crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES])
158 {
159 randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
160 }
161