Home | History | Annotate | Line # | Download | only in sodium
      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 > UINT64_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES) {
     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