1/* 2version 20140420 3D. J. Bernstein 4Public 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 18static int 19stream_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 63static int 64stream_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 114struct 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