8 #include "crypto_core_hsalsa20.h"
9 #include "crypto_onetimeauth_poly1305.h"
10 #include "crypto_secretbox.h"
11 #include "crypto_stream_salsa20.h"
14 static const unsigned char sigma[16] = {
15 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'
19 crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
20 const unsigned char *m,
21 unsigned long long mlen, const unsigned char *n,
22 const unsigned char *k)
24 crypto_onetimeauth_poly1305_state state;
25 unsigned char block0[64U];
26 unsigned char subkey[crypto_stream_salsa20_KEYBYTES];
28 unsigned long long mlen0;
30 crypto_core_hsalsa20(subkey, n, k, sigma);
32 if (((uintptr_t) c >= (uintptr_t) m &&
33 (uintptr_t) c - (uintptr_t) m < mlen) ||
34 ((uintptr_t) m >= (uintptr_t) c &&
35 (uintptr_t) m - (uintptr_t) c < mlen)) {
39 memset(block0, 0U, crypto_secretbox_ZEROBYTES);
40 (void) sizeof(int[64U >= crypto_secretbox_ZEROBYTES ? 1 : -1]);
42 if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
43 mlen0 = 64U - crypto_secretbox_ZEROBYTES;
45 for (i = 0U; i < mlen0; i++) {
46 block0[i + crypto_secretbox_ZEROBYTES] = m[i];
48 crypto_stream_salsa20_xor(block0, block0,
49 mlen0 + crypto_secretbox_ZEROBYTES,
51 (void) sizeof(int[crypto_secretbox_ZEROBYTES >=
52 crypto_onetimeauth_poly1305_KEYBYTES ? 1 : -1]);
53 crypto_onetimeauth_poly1305_init(&state, block0);
55 memcpy(c, block0 + crypto_secretbox_ZEROBYTES, mlen0);
56 sodium_memzero(block0, sizeof block0);
58 crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0,
61 sodium_memzero(subkey, sizeof subkey);
63 crypto_onetimeauth_poly1305_update(&state, c, mlen);
64 crypto_onetimeauth_poly1305_final(&state, mac);
65 sodium_memzero(&state, sizeof state);
71 crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
72 unsigned long long mlen, const unsigned char *n,
73 const unsigned char *k)
75 if (mlen > SIZE_MAX - crypto_secretbox_MACBYTES) {
78 return crypto_secretbox_detached(c + crypto_secretbox_MACBYTES,
83 crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c,
84 const unsigned char *mac,
85 unsigned long long clen,
86 const unsigned char *n,
87 const unsigned char *k)
89 unsigned char block0[64U];
90 unsigned char subkey[crypto_stream_salsa20_KEYBYTES];
92 unsigned long long mlen0;
94 crypto_core_hsalsa20(subkey, n, k, sigma);
95 crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES,
97 if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) {
98 sodium_memzero(subkey, sizeof subkey);
101 if (((uintptr_t) c >= (uintptr_t) m &&
102 (uintptr_t) c - (uintptr_t) m < clen) ||
103 ((uintptr_t) m >= (uintptr_t) c &&
104 (uintptr_t) m - (uintptr_t) c < clen)) {
109 if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
110 mlen0 = 64U - crypto_secretbox_ZEROBYTES;
112 memcpy(block0 + crypto_secretbox_ZEROBYTES, c, mlen0);
113 crypto_stream_salsa20_xor(block0, block0,
114 crypto_secretbox_ZEROBYTES + mlen0,
116 for (i = 0U; i < mlen0; i++) {
117 m[i] = block0[i + crypto_secretbox_ZEROBYTES];
120 crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0,
123 sodium_memzero(subkey, sizeof subkey);
129 crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
130 unsigned long long clen, const unsigned char *n,
131 const unsigned char *k)
133 if (clen < crypto_secretbox_MACBYTES) {
136 return crypto_secretbox_open_detached(m, c + crypto_secretbox_MACBYTES, c,
137 clen - crypto_secretbox_MACBYTES,