-c zero: assume zero counter value.
[tfcrypt.git] / tfe.c
1 #include <string.h>
2 #include "tfdef.h"
3 #include "tfe.h"
4
5 void tfe_init_iv(struct tfe_stream *tfe, const void *key, const void *iv)
6 {
7         memset(tfe, 0, sizeof(struct tfe_stream));
8         memcpy(tfe->key, key, TF_KEY_SIZE);
9         if (iv) memcpy(tfe->iv, iv, TF_BLOCK_SIZE);
10         tfe->carry_bytes = 0;
11 }
12
13 void tfe_init(struct tfe_stream *tfe, const void *key)
14 {
15         tfe_init_iv(tfe, key, NULL);
16 }
17
18 void tfe_emit(void *dst, size_t szdst, struct tfe_stream *tfe)
19 {
20         TF_BYTE_TYPE *udst = dst;
21         size_t sz = szdst;
22
23         if (!dst && szdst == 0) {
24                 memset(tfe, 0, sizeof(struct tfe_stream));
25                 return;
26         }
27
28         if (tfe->carry_bytes > 0) {
29                 if (tfe->carry_bytes > szdst) {
30                         memcpy(udst, tfe->carry_block, szdst);
31                         memmove(tfe->carry_block, tfe->carry_block+szdst, tfe->carry_bytes-szdst);
32                         tfe->carry_bytes -= szdst;
33                         return;
34                 }
35
36                 memcpy(udst, tfe->carry_block, tfe->carry_bytes);
37                 udst += tfe->carry_bytes;
38                 sz -= tfe->carry_bytes;
39                 tfe->carry_bytes = 0;
40         }
41
42         if (sz >= TF_BLOCK_SIZE) {
43                 do {
44                         tf_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
45                         memcpy(udst, tfe->iv, TF_BLOCK_SIZE);
46                         data_to_words(udst, TF_BLOCK_SIZE);
47                         udst += TF_BLOCK_SIZE;
48                 } while ((sz -= TF_BLOCK_SIZE) >= TF_BLOCK_SIZE);
49         }
50
51         if (sz) {
52                 tf_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
53                 memcpy(udst, tfe->iv, sz);
54                 data_to_words(udst, TF_BLOCK_SIZE);
55                 udst = (TF_BYTE_TYPE *)tfe->iv;
56                 tfe->carry_bytes = TF_BLOCK_SIZE-sz;
57                 memcpy(tfe->carry_block, udst+sz, tfe->carry_bytes);
58         }
59 }