1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file f8_start.c
7 F8 implementation, start chain, Tom St Denis
8 */
9
10
11 #ifdef LTC_F8_MODE
12
13 /**
14 Initialize an F8 context
15 @param cipher The index of the cipher desired
16 @param IV The initialization vector
17 @param key The secret key
18 @param keylen The length of the secret key (octets)
19 @param salt_key The salting key for the IV
20 @param skeylen The length of the salting key (octets)
21 @param num_rounds Number of rounds in the cipher desired (0 for default)
22 @param f8 The F8 state to initialize
23 @return CRYPT_OK if successful
24 */
f8_start(int cipher,const unsigned char * IV,const unsigned char * key,int keylen,const unsigned char * salt_key,int skeylen,int num_rounds,symmetric_F8 * f8)25 int f8_start( int cipher, const unsigned char *IV,
26 const unsigned char *key, int keylen,
27 const unsigned char *salt_key, int skeylen,
28 int num_rounds, symmetric_F8 *f8)
29 {
30 int x, err;
31 unsigned char tkey[MAXBLOCKSIZE];
32
33 LTC_ARGCHK(IV != NULL);
34 LTC_ARGCHK(key != NULL);
35 LTC_ARGCHK(salt_key != NULL);
36 LTC_ARGCHK(f8 != NULL);
37
38 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
39 return err;
40 }
41
42 #ifdef LTC_FAST
43 if (cipher_descriptor[cipher]->block_length % sizeof(LTC_FAST_TYPE)) {
44 return CRYPT_INVALID_ARG;
45 }
46 #endif
47
48 /* copy details */
49 f8->blockcnt = 0;
50 f8->cipher = cipher;
51 f8->blocklen = cipher_descriptor[cipher]->block_length;
52 f8->padlen = f8->blocklen;
53
54 /* now get key ^ salt_key [extend salt_ket with 0x55 as required to match length] */
55 zeromem(tkey, sizeof(tkey));
56 for (x = 0; x < keylen && x < (int)sizeof(tkey); x++) {
57 tkey[x] = key[x];
58 }
59 for (x = 0; x < skeylen && x < (int)sizeof(tkey); x++) {
60 tkey[x] ^= salt_key[x];
61 }
62 for (; x < keylen && x < (int)sizeof(tkey); x++) {
63 tkey[x] ^= 0x55;
64 }
65
66 /* now encrypt with tkey[0..keylen-1] the IV and use that as the IV */
67 if ((err = cipher_descriptor[cipher]->setup(tkey, keylen, num_rounds, &f8->key)) != CRYPT_OK) {
68 return err;
69 }
70
71 /* encrypt IV */
72 if ((err = cipher_descriptor[f8->cipher]->ecb_encrypt(IV, f8->MIV, &f8->key)) != CRYPT_OK) {
73 cipher_descriptor[f8->cipher]->done(&f8->key);
74 return err;
75 }
76 zeromem(tkey, sizeof(tkey));
77 zeromem(f8->IV, sizeof(f8->IV));
78
79 /* terminate this cipher */
80 cipher_descriptor[f8->cipher]->done(&f8->key);
81
82 /* init the cipher */
83 return cipher_descriptor[cipher]->setup(key, keylen, num_rounds, &f8->key);
84 }
85
86 #endif
87