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 16int 17crypto_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 42int 43crypto_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 70int 71crypto_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 96int 97crypto_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 126size_t 127crypto_aead_xchacha20poly1305_ietf_keybytes(void) 128{ 129 return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; 130} 131 132size_t 133crypto_aead_xchacha20poly1305_ietf_npubbytes(void) 134{ 135 return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; 136} 137 138size_t 139crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) 140{ 141 return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; 142} 143 144size_t 145crypto_aead_xchacha20poly1305_ietf_abytes(void) 146{ 147 return crypto_aead_xchacha20poly1305_ietf_ABYTES; 148} 149 150size_t 151crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void) 152{ 153 return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; 154} 155 156void 157crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) 158{ 159 randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES); 160} 161