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 #include "tomcrypt_private.h"
11 
12 /**
13   @file f8_encrypt.c
14   F8 implementation, encrypt data, Tom St Denis
15 */
16 
17 #ifdef LTC_F8_MODE
18 
19 /**
20   F8 encrypt
21   @param pt     Plaintext
22   @param ct     [out] Ciphertext
23   @param len    Length of plaintext (octets)
24   @param f8     F8 state
25   @return CRYPT_OK if successful
26 */
f8_encrypt(const unsigned char * pt,unsigned char * ct,unsigned long len,symmetric_F8 * f8)27 int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8)
28 {
29    int           err, x;
30    unsigned char buf[MAXBLOCKSIZE];
31    LTC_ARGCHK(pt != NULL);
32    LTC_ARGCHK(ct != NULL);
33    LTC_ARGCHK(f8 != NULL);
34    if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) {
35        return err;
36    }
37 
38    /* is blocklen/padlen valid? */
39    if (f8->blocklen < 0 || f8->blocklen > (int)sizeof(f8->IV) ||
40        f8->padlen   < 0 || f8->padlen   > (int)sizeof(f8->IV)) {
41       return CRYPT_INVALID_ARG;
42    }
43 
44    zeromem(buf, sizeof(buf));
45 
46    /* make sure the pad is empty */
47    if (f8->padlen == f8->blocklen) {
48       /* xor of IV, MIV and blockcnt == what goes into cipher */
49       STORE32H(f8->blockcnt, (buf+(f8->blocklen-4)));
50       ++(f8->blockcnt);
51       for (x = 0; x < f8->blocklen; x++) {
52           f8->IV[x] ^= f8->MIV[x] ^ buf[x];
53       }
54       if ((err = cipher_descriptor[f8->cipher]->ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) {
55          return err;
56       }
57       f8->padlen = 0;
58    }
59 
60 #ifdef LTC_FAST
61    if (f8->padlen == 0) {
62       while (len >= (unsigned long)f8->blocklen) {
63          STORE32H(f8->blockcnt, (buf+(f8->blocklen-4)));
64          ++(f8->blockcnt);
65          for (x = 0; x < f8->blocklen; x += sizeof(LTC_FAST_TYPE)) {
66              *(LTC_FAST_TYPE_PTR_CAST(&ct[x])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&f8->IV[x]));
67              *(LTC_FAST_TYPE_PTR_CAST(&f8->IV[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&f8->MIV[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&buf[x]));
68          }
69          if ((err = cipher_descriptor[f8->cipher]->ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) {
70             return err;
71          }
72          len -= x;
73          pt  += x;
74          ct  += x;
75       }
76    }
77 #endif
78 
79    while (len > 0) {
80        if (f8->padlen == f8->blocklen) {
81           /* xor of IV, MIV and blockcnt == what goes into cipher */
82           STORE32H(f8->blockcnt, (buf+(f8->blocklen-4)));
83           ++(f8->blockcnt);
84           for (x = 0; x < f8->blocklen; x++) {
85               f8->IV[x] ^= f8->MIV[x] ^ buf[x];
86           }
87           if ((err = cipher_descriptor[f8->cipher]->ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) {
88              return err;
89           }
90           f8->padlen = 0;
91        }
92        *ct++ = *pt++ ^ f8->IV[f8->padlen++];
93        --len;
94    }
95    return CRYPT_OK;
96 }
97 
98 #endif
99 
100 /* ref:         $Format:%D$ */
101 /* git commit:  $Format:%H$ */
102 /* commit time: $Format:%ai$ */
103