1 #include "crypto_stream_salsa20.h"
2 #include "private/common.h"
3 #include "private/implementations.h"
4 #include "randombytes.h"
5 #include "runtime.h"
6 #include "stream_salsa20.h"
7 
8 #ifdef HAVE_AMD64_ASM
9 # include "xmm6/salsa20_xmm6.h"
10 #else
11 # include "ref/salsa20_ref.h"
12 #endif
13 #if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H)
14 # include "xmm6int/salsa20_xmm6int-sse2.h"
15 #endif
16 #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
17     defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
18 # include "xmm6int/salsa20_xmm6int-avx2.h"
19 #endif
20 
21 #if HAVE_AMD64_ASM
22 static const crypto_stream_salsa20_implementation *implementation =
23     &crypto_stream_salsa20_xmm6_implementation;
24 #else
25 static const crypto_stream_salsa20_implementation *implementation =
26     &crypto_stream_salsa20_ref_implementation;
27 #endif
28 
29 size_t
30 crypto_stream_salsa20_keybytes(void)
31 {
32     return crypto_stream_salsa20_KEYBYTES;
33 }
34 
35 size_t
36 crypto_stream_salsa20_noncebytes(void)
37 {
38     return crypto_stream_salsa20_NONCEBYTES;
39 }
40 
41 size_t
42 crypto_stream_salsa20_messagebytes_max(void)
43 {
44     return crypto_stream_salsa20_MESSAGEBYTES_MAX;
45 }
46 
47 int
48 crypto_stream_salsa20(unsigned char *c, unsigned long long clen,
49                       const unsigned char *n, const unsigned char *k)
50 {
51     return implementation->stream(c, clen, n, k);
52 }
53 
54 int
55 crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m,
56                              unsigned long long mlen,
57                              const unsigned char *n, uint64_t ic,
58                              const unsigned char *k)
59 {
60     return implementation->stream_xor_ic(c, m, mlen, n, ic, k);
61 }
62 
63 int
64 crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m,
65                           unsigned long long mlen, const unsigned char *n,
66                           const unsigned char *k)
67 {
68     return implementation->stream_xor_ic(c, m, mlen, n, 0U, k);
69 }
70 
71 void
72 crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES])
73 {
74     randombytes_buf(k, crypto_stream_salsa20_KEYBYTES);
75 }
76 
77 int
78 _crypto_stream_salsa20_pick_best_implementation(void)
79 {
80 #ifdef HAVE_AMD64_ASM
81     implementation = &crypto_stream_salsa20_xmm6_implementation;
82 #else
83     implementation = &crypto_stream_salsa20_ref_implementation;
84 #endif
85 
86 #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
87     defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
88     if (sodium_runtime_has_avx2()) {
89         implementation = &crypto_stream_salsa20_xmm6int_avx2_implementation;
90         return 0;
91     }
92 #endif
93 #if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H)
94     if (sodium_runtime_has_sse2()) {
95         implementation = &crypto_stream_salsa20_xmm6int_sse2_implementation;
96         return 0;
97     }
98 #endif
99     return 0; /* LCOV_EXCL_LINE */
100 }
101