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 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 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 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 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 127 crypto_aead_xchacha20poly1305_ietf_keybytes(void) 128 { 129 return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; 130 } 131 132 size_t 133 crypto_aead_xchacha20poly1305_ietf_npubbytes(void) 134 { 135 return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; 136 } 137 138 size_t 139 crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) 140 { 141 return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; 142 } 143 144 size_t 145 crypto_aead_xchacha20poly1305_ietf_abytes(void) 146 { 147 return crypto_aead_xchacha20poly1305_ietf_ABYTES; 148 } 149 150 size_t 151 crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void) 152 { 153 return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; 154 } 155 156 void 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