tfcrypt: fixing hash output stream.
[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         data_to_words(tfe->key, TF_KEY_SIZE);
10         if (iv) {
11                 memcpy(tfe->iv, iv, TF_BLOCK_SIZE);
12                 data_to_words(tfe->iv, TF_BLOCK_SIZE);
13         }
14         tfe->carry_bytes = 0;
15 }
16
17 void tfe_init(struct tfe_stream *tfe, const void *key)
18 {
19         tfe_init_iv(tfe, key, NULL);
20 }
21
22 void tfe_emit(void *dst, size_t szdst, struct tfe_stream *tfe)
23 {
24         TF_BYTE_TYPE *udst = dst;
25         size_t sz = szdst;
26
27         if (!dst && szdst == 0) {
28                 memset(tfe, 0, sizeof(struct tfe_stream));
29                 return;
30         }
31
32         if (tfe->carry_bytes > 0) {
33                 if (tfe->carry_bytes > szdst) {
34                         memcpy(udst, tfe->carry_block, szdst);
35                         memmove(tfe->carry_block, tfe->carry_block+szdst, tfe->carry_bytes-szdst);
36                         tfe->carry_bytes -= szdst;
37                         return;
38                 }
39
40                 memcpy(udst, tfe->carry_block, tfe->carry_bytes);
41                 udst += tfe->carry_bytes;
42                 sz -= tfe->carry_bytes;
43                 tfe->carry_bytes = 0;
44         }
45
46         if (sz >= TF_BLOCK_SIZE) {
47                 do {
48                         tf_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
49                         memcpy(udst, tfe->iv, TF_BLOCK_SIZE);
50                         data_to_words(udst, TF_BLOCK_SIZE);
51                         udst += TF_BLOCK_SIZE;
52                 } while ((sz -= TF_BLOCK_SIZE) >= TF_BLOCK_SIZE);
53         }
54
55         if (sz) {
56                 tf_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
57                 memcpy(udst, tfe->iv, sz);
58                 data_to_words(udst, TF_BLOCK_SIZE);
59                 udst = (TF_BYTE_TYPE *)tfe->iv;
60                 tfe->carry_bytes = TF_BLOCK_SIZE-sz;
61                 memcpy(tfe->carry_block, udst+sz, tfe->carry_bytes);
62         }
63 }