Home | History | Annotate | Line # | Download | only in crypto_secretbox
      1 
      2 #include <assert.h>
      3 #include <limits.h>
      4 #include <stdint.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #include "core.h"
      9 #include "crypto_core_hsalsa20.h"
     10 #include "crypto_onetimeauth_poly1305.h"
     11 #include "crypto_secretbox.h"
     12 #include "crypto_stream_salsa20.h"
     13 #include "private/common.h"
     14 #include "utils.h"
     15 
     16 int
     17 crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
     18                           const unsigned char *m,
     19                           unsigned long long mlen, const unsigned char *n,
     20                           const unsigned char *k)
     21 {
     22     crypto_onetimeauth_poly1305_state state;
     23     unsigned char                     block0[64U];
     24     unsigned char                     subkey[crypto_stream_salsa20_KEYBYTES];
     25     unsigned long long                i;
     26     unsigned long long                mlen0;
     27 
     28     crypto_core_hsalsa20(subkey, n, k, NULL);
     29 
     30     if (((uintptr_t) c > (uintptr_t) m &&
     31          (uintptr_t) c - (uintptr_t) m < mlen) ||
     32         ((uintptr_t) m > (uintptr_t) c &&
     33          (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */
     34         memmove(c, m, mlen);
     35         m = c;
     36     }
     37     memset(block0, 0U, crypto_secretbox_ZEROBYTES);
     38     COMPILER_ASSERT(64U >= crypto_secretbox_ZEROBYTES);
     39     mlen0 = mlen;
     40     if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
     41         mlen0 = 64U - crypto_secretbox_ZEROBYTES;
     42     }
     43     for (i = 0U; i < mlen0; i++) {
     44         block0[i + crypto_secretbox_ZEROBYTES] = m[i];
     45     }
     46     crypto_stream_salsa20_xor(block0, block0,
     47                               mlen0 + crypto_secretbox_ZEROBYTES,
     48                               n + 16, subkey);
     49     COMPILER_ASSERT(crypto_secretbox_ZEROBYTES >=
     50                     crypto_onetimeauth_poly1305_KEYBYTES);
     51     crypto_onetimeauth_poly1305_init(&state, block0);
     52 
     53     for (i = 0U; i < mlen0; i++) {
     54         c[i] = block0[crypto_secretbox_ZEROBYTES + i];
     55     }
     56     sodium_memzero(block0, sizeof block0);
     57     if (mlen > mlen0) {
     58         crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0,
     59                                      n + 16, 1U, subkey);
     60     }
     61     sodium_memzero(subkey, sizeof subkey);
     62 
     63     crypto_onetimeauth_poly1305_update(&state, c, mlen);
     64     crypto_onetimeauth_poly1305_final(&state, mac);
     65     sodium_memzero(&state, sizeof state);
     66 
     67     return 0;
     68 }
     69 
     70 int
     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)
     74 {
     75     if (mlen > crypto_secretbox_MESSAGEBYTES_MAX) {
     76         sodium_misuse();
     77     }
     78     return crypto_secretbox_detached(c + crypto_secretbox_MACBYTES,
     79                                      c, m, mlen, n, k);
     80 }
     81 
     82 int
     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)
     88 {
     89     unsigned char      block0[64U];
     90     unsigned char      subkey[crypto_stream_salsa20_KEYBYTES];
     91     unsigned long long i;
     92     unsigned long long mlen0;
     93 
     94     crypto_core_hsalsa20(subkey, n, k, NULL);
     95     crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES,
     96                           n + 16, subkey);
     97     if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) {
     98         sodium_memzero(subkey, sizeof subkey);
     99         return -1;
    100     }
    101     if (m == NULL) {
    102         return 0;
    103     }
    104     if (((uintptr_t) c >= (uintptr_t) m &&
    105          (uintptr_t) c - (uintptr_t) m < clen) ||
    106         ((uintptr_t) m >= (uintptr_t) c &&
    107          (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */
    108         memmove(m, c, clen);
    109         c = m;
    110     }
    111     mlen0 = clen;
    112     if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
    113         mlen0 = 64U - crypto_secretbox_ZEROBYTES;
    114     }
    115     for (i = 0U; i < mlen0; i++) {
    116         block0[crypto_secretbox_ZEROBYTES + i] = c[i];
    117     }
    118     crypto_stream_salsa20_xor(block0, block0,
    119                               crypto_secretbox_ZEROBYTES + mlen0,
    120                               n + 16, subkey);
    121     for (i = 0U; i < mlen0; i++) {
    122         m[i] = block0[i + crypto_secretbox_ZEROBYTES];
    123     }
    124     if (clen > mlen0) {
    125         crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0,
    126                                      n + 16, 1U, subkey);
    127     }
    128     sodium_memzero(subkey, sizeof subkey);
    129 
    130     return 0;
    131 }
    132 
    133 int
    134 crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
    135                            unsigned long long clen, const unsigned char *n,
    136                            const unsigned char *k)
    137 {
    138     if (clen < crypto_secretbox_MACBYTES) {
    139         return -1;
    140     }
    141     return crypto_secretbox_open_detached(m, c + crypto_secretbox_MACBYTES, c,
    142                                           clen - crypto_secretbox_MACBYTES,
    143                                           n, k);
    144 }
    145