1 2 #include <stdint.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include "crypto_stream_salsa20.h" 7 #include "private/common.h" 8 #include "private/sse2_64_32.h" 9 #include "utils.h" 10 11 #ifdef HAVE_EMMINTRIN_H 12 13 # ifdef __GNUC__ 14 # pragma GCC target("sse2") 15 # endif 16 # include <emmintrin.h> 17 18 # include "../stream_salsa20.h" 19 # include "salsa20_xmm6int-sse2.h" 20 21 # define ROUNDS 20 22 23 typedef struct salsa_ctx { 24 uint32_t input[16]; 25 } salsa_ctx; 26 27 static const int TR[16] = { 28 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3 29 }; 30 31 static void 32 salsa_keysetup(salsa_ctx *ctx, const uint8_t *k) 33 { 34 ctx->input[TR[1]] = LOAD32_LE(k + 0); 35 ctx->input[TR[2]] = LOAD32_LE(k + 4); 36 ctx->input[TR[3]] = LOAD32_LE(k + 8); 37 ctx->input[TR[4]] = LOAD32_LE(k + 12); 38 ctx->input[TR[11]] = LOAD32_LE(k + 16); 39 ctx->input[TR[12]] = LOAD32_LE(k + 20); 40 ctx->input[TR[13]] = LOAD32_LE(k + 24); 41 ctx->input[TR[14]] = LOAD32_LE(k + 28); 42 ctx->input[TR[0]] = 0x61707865; 43 ctx->input[TR[5]] = 0x3320646e; 44 ctx->input[TR[10]] = 0x79622d32; 45 ctx->input[TR[15]] = 0x6b206574; 46 } 47 48 static void 49 salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter) 50 { 51 ctx->input[TR[6]] = LOAD32_LE(iv + 0); 52 ctx->input[TR[7]] = LOAD32_LE(iv + 4); 53 ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0); 54 ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4); 55 } 56 57 static void 58 salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c, 59 unsigned long long bytes) 60 { 61 uint32_t * const x = &ctx->input[0]; 62 63 if (!bytes) { 64 return; /* LCOV_EXCL_LINE */ 65 } 66 67 #include "u4.h" 68 #include "u1.h" 69 #include "u0.h" 70 } 71 72 static int 73 stream_sse2(unsigned char *c, unsigned long long clen, const unsigned char *n, 74 const unsigned char *k) 75 { 76 struct salsa_ctx ctx; 77 78 if (!clen) { 79 return 0; 80 } 81 COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8); 82 salsa_keysetup(&ctx, k); 83 salsa_ivsetup(&ctx, n, NULL); 84 memset(c, 0, clen); 85 salsa20_encrypt_bytes(&ctx, c, c, clen); 86 sodium_memzero(&ctx, sizeof ctx); 87 88 return 0; 89 } 90 91 static int 92 stream_sse2_xor_ic(unsigned char *c, const unsigned char *m, 93 unsigned long long mlen, const unsigned char *n, uint64_t ic, 94 const unsigned char *k) 95 { 96 struct salsa_ctx ctx; 97 uint8_t ic_bytes[8]; 98 uint32_t ic_high; 99 uint32_t ic_low; 100 101 if (!mlen) { 102 return 0; 103 } 104 ic_high = (uint32_t) (ic >> 32); 105 ic_low = (uint32_t) (ic); 106 STORE32_LE(&ic_bytes[0], ic_low); 107 STORE32_LE(&ic_bytes[4], ic_high); 108 salsa_keysetup(&ctx, k); 109 salsa_ivsetup(&ctx, n, ic_bytes); 110 salsa20_encrypt_bytes(&ctx, m, c, mlen); 111 sodium_memzero(&ctx, sizeof ctx); 112 113 return 0; 114 } 115 116 struct crypto_stream_salsa20_implementation 117 crypto_stream_salsa20_xmm6int_sse2_implementation = { 118 SODIUM_C99(.stream =) stream_sse2, 119 SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic 120 }; 121 122 #endif 123