1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 
11 /* The implementation is based on:
12  * "Salsa20 specification", http://cr.yp.to/snuffle/spec.pdf
13  * and salsa20-ref.c version 20051118
14  * Public domain from D. J. Bernstein
15  */
16 
17 #include "tomcrypt_private.h"
18 
19 #ifdef LTC_SALSA20
20 
21 static const char * const sigma = "expand 32-byte k";
22 static const char * const tau   = "expand 16-byte k";
23 
24 /**
25    Initialize an Salsa20 context (only the key)
26    @param st        [out] The destination of the Salsa20 state
27    @param key       The secret key
28    @param keylen    The length of the secret key (octets)
29    @param rounds    Number of rounds (e.g. 20 for Salsa20)
30    @return CRYPT_OK if successful
31 */
salsa20_setup(salsa20_state * st,const unsigned char * key,unsigned long keylen,int rounds)32 int salsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long keylen, int rounds)
33 {
34    const char *constants;
35 
36    LTC_ARGCHK(st  != NULL);
37    LTC_ARGCHK(key != NULL);
38    LTC_ARGCHK(keylen == 32 || keylen == 16);
39 
40    if (rounds == 0) rounds = 20;
41    LTC_ARGCHK(rounds % 2 == 0); /* number of rounds must be evenly divisible by 2 */
42 
43    LOAD32L(st->input[1],  key + 0);
44    LOAD32L(st->input[2],  key + 4);
45    LOAD32L(st->input[3],  key + 8);
46    LOAD32L(st->input[4],  key + 12);
47    if (keylen == 32) { /* 256bit */
48       key += 16;
49       constants = sigma;
50    } else { /* 128bit */
51       constants = tau;
52    }
53    LOAD32L(st->input[11], key + 0);
54    LOAD32L(st->input[12], key + 4);
55    LOAD32L(st->input[13], key + 8);
56    LOAD32L(st->input[14], key + 12);
57    LOAD32L(st->input[ 0],  constants + 0);
58    LOAD32L(st->input[ 5],  constants + 4);
59    LOAD32L(st->input[10],  constants + 8);
60    LOAD32L(st->input[15],  constants + 12);
61    st->rounds = rounds;     /* default is 20 for salsa20 */
62    st->ivlen = 0;           /* will be set later by salsa20_ivctr(32|64) */
63    return CRYPT_OK;
64 }
65 
66 #endif
67 
68 /* ref:         $Format:%D$ */
69 /* git commit:  $Format:%H$ */
70 /* commit time: $Format:%ai$ */
71