Home | History | Annotate | Line # | Download | only in ref
      1 /*
      2 version 20140420
      3 D. J. Bernstein
      4 Public domain.
      5 */
      6 
      7 #include <stdint.h>
      8 
      9 #include "crypto_core_salsa20.h"
     10 #include "crypto_stream_salsa20.h"
     11 #include "utils.h"
     12 
     13 #include "../stream_salsa20.h"
     14 #include "salsa20_ref.h"
     15 
     16 #ifndef HAVE_AMD64_ASM
     17 
     18 static int
     19 stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n,
     20            const unsigned char *k)
     21 {
     22     unsigned char in[16];
     23     unsigned char block[64];
     24     unsigned char kcopy[32];
     25     unsigned int  i;
     26     unsigned int  u;
     27 
     28     if (!clen) {
     29         return 0;
     30     }
     31     for (i = 0; i < 32; i++) {
     32         kcopy[i] = k[i];
     33     }
     34     for (i = 0; i < 8; i++) {
     35         in[i] = n[i];
     36     }
     37     for (i = 8; i < 16; i++) {
     38         in[i] = 0;
     39     }
     40     while (clen >= 64) {
     41         crypto_core_salsa20(c, in, kcopy, NULL);
     42         u = 1;
     43         for (i = 8; i < 16; i++) {
     44             u += (unsigned int) in[i];
     45             in[i] = u;
     46             u >>= 8;
     47         }
     48         clen -= 64;
     49         c += 64;
     50     }
     51     if (clen) {
     52         crypto_core_salsa20(block, in, kcopy, NULL);
     53         for (i = 0; i < (unsigned int) clen; i++) {
     54             c[i] = block[i];
     55         }
     56     }
     57     sodium_memzero(block, sizeof block);
     58     sodium_memzero(kcopy, sizeof kcopy);
     59 
     60     return 0;
     61 }
     62 
     63 static int
     64 stream_ref_xor_ic(unsigned char *c, const unsigned char *m,
     65                   unsigned long long mlen, const unsigned char *n, uint64_t ic,
     66                   const unsigned char *k)
     67 {
     68     unsigned char in[16];
     69     unsigned char block[64];
     70     unsigned char kcopy[32];
     71     unsigned int  i;
     72     unsigned int  u;
     73 
     74     if (!mlen) {
     75         return 0;
     76     }
     77     for (i = 0; i < 32; i++) {
     78         kcopy[i] = k[i];
     79     }
     80     for (i = 0; i < 8; i++) {
     81         in[i] = n[i];
     82     }
     83     for (i = 8; i < 16; i++) {
     84         in[i] = (unsigned char) (ic & 0xff);
     85         ic >>= 8;
     86     }
     87     while (mlen >= 64) {
     88         crypto_core_salsa20(block, in, kcopy, NULL);
     89         for (i = 0; i < 64; i++) {
     90             c[i] = m[i] ^ block[i];
     91         }
     92         u = 1;
     93         for (i = 8; i < 16; i++) {
     94             u += (unsigned int) in[i];
     95             in[i] = u;
     96             u >>= 8;
     97         }
     98         mlen -= 64;
     99         c += 64;
    100         m += 64;
    101     }
    102     if (mlen) {
    103         crypto_core_salsa20(block, in, kcopy, NULL);
    104         for (i = 0; i < (unsigned int) mlen; i++) {
    105             c[i] = m[i] ^ block[i];
    106         }
    107     }
    108     sodium_memzero(block, sizeof block);
    109     sodium_memzero(kcopy, sizeof kcopy);
    110 
    111     return 0;
    112 }
    113 
    114 struct crypto_stream_salsa20_implementation
    115     crypto_stream_salsa20_ref_implementation = {
    116         SODIUM_C99(.stream =) stream_ref,
    117         SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic,
    118     };
    119 
    120 #endif
    121