1 /* 2 version 20140420 3 D. J. Bernstein 4 Public domain. 5 */ 6 7 #include <stdint.h> 8 9 #include "crypto_core_salsa2012.h" 10 #include "crypto_stream_salsa2012.h" 11 #include "utils.h" 12 13 int 14 crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, 15 const unsigned char *n, const unsigned char *k) 16 { 17 unsigned char in[16]; 18 unsigned char block[64]; 19 unsigned char kcopy[32]; 20 unsigned int i; 21 unsigned int u; 22 23 if (!clen) { 24 return 0; 25 } 26 for (i = 0; i < 32; ++i) { 27 kcopy[i] = k[i]; 28 } 29 for (i = 0; i < 8; ++i) { 30 in[i] = n[i]; 31 } 32 for (i = 8; i < 16; ++i) { 33 in[i] = 0; 34 } 35 while (clen >= 64) { 36 crypto_core_salsa2012(c, in, kcopy, NULL); 37 u = 1; 38 for (i = 8; i < 16; ++i) { 39 u += (unsigned int)in[i]; 40 in[i] = u; 41 u >>= 8; 42 } 43 clen -= 64; 44 c += 64; 45 } 46 if (clen) { 47 crypto_core_salsa2012(block, in, kcopy, NULL); 48 for (i = 0; i < (unsigned int)clen; ++i) { 49 c[i] = block[i]; 50 } 51 } 52 sodium_memzero(block, sizeof block); 53 sodium_memzero(kcopy, sizeof kcopy); 54 55 return 0; 56 } 57 58 int 59 crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, 60 unsigned long long mlen, const unsigned char *n, 61 const unsigned char *k) 62 { 63 unsigned char in[16]; 64 unsigned char block[64]; 65 unsigned char kcopy[32]; 66 unsigned int i; 67 unsigned int u; 68 69 if (!mlen) { 70 return 0; 71 } 72 for (i = 0; i < 32; ++i) { 73 kcopy[i] = k[i]; 74 } 75 for (i = 0; i < 8; ++i) { 76 in[i] = n[i]; 77 } 78 for (i = 8; i < 16; ++i) { 79 in[i] = 0; 80 } 81 while (mlen >= 64) { 82 crypto_core_salsa2012(block, in, kcopy, NULL); 83 for (i = 0; i < 64; ++i) { 84 c[i] = m[i] ^ block[i]; 85 } 86 u = 1; 87 for (i = 8; i < 16; ++i) { 88 u += (unsigned int)in[i]; 89 in[i] = u; 90 u >>= 8; 91 } 92 mlen -= 64; 93 c += 64; 94 m += 64; 95 } 96 if (mlen) { 97 crypto_core_salsa2012(block, in, kcopy, NULL); 98 for (i = 0; i < (unsigned int)mlen; ++i) { 99 c[i] = m[i] ^ block[i]; 100 } 101 } 102 sodium_memzero(block, sizeof block); 103 sodium_memzero(kcopy, sizeof kcopy); 104 105 return 0; 106 } 107