macros.h replaced with smaller headers, U8TO*_?E() renamed and converted to static...
[rofl0r-kripto.git] / lib / stream / ofb.c
blob54407daa894034fa7d81def2d786ed1faee32e80
1 /*
2 * Copyright (C) 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
15 #include <stdint.h>
16 #include <string.h>
17 #include <stdlib.h>
19 #include <kripto/cast.h>
20 #include <kripto/memwipe.h>
21 #include <kripto/block.h>
22 #include <kripto/stream.h>
23 #include <kripto/desc/stream.h>
25 #include <kripto/stream/ofb.h>
27 struct kripto_stream
29 const kripto_stream_desc *desc;
30 kripto_block *block;
31 uint8_t *prev;
32 unsigned int blocksize;
33 unsigned int used;
36 static void ofb_crypt
38 kripto_stream *s,
39 const void *in,
40 void *out,
41 size_t len
44 size_t i;
46 for(i = 0; i < len; i++)
48 if(s->used == s->blocksize)
50 kripto_block_encrypt(s->block, s->prev, s->prev);
51 s->used = 0;
54 U8(out)[i] = CU8(in)[i] ^ s->prev[s->used++];
58 static void ofb_prng
60 kripto_stream *s,
61 void *out,
62 size_t len
65 size_t i;
67 for(i = 0; i < len; i++)
69 if(s->used == s->blocksize)
71 kripto_block_encrypt(s->block, s->prev, s->prev);
72 s->used = 0;
75 U8(out)[i] = s->prev[s->used++];
79 static void ofb_destroy(kripto_stream *s)
81 kripto_block_destroy(s->block);
82 kripto_memwipe(s, sizeof(kripto_stream) + s->blocksize);
83 free(s);
86 struct ext
88 kripto_stream_desc desc;
89 const kripto_block_desc *block;
92 #define EXT(X) ((const struct ext *)(X))
94 static kripto_stream *ofb_create
96 const kripto_stream_desc *desc,
97 unsigned int rounds,
98 const void *key,
99 unsigned int key_len,
100 const void *iv,
101 unsigned int iv_len
104 kripto_stream *s;
106 s = malloc(sizeof(kripto_stream) + desc->maxiv);
107 if(!s) return 0;
109 s->desc = desc;
111 s->used = s->blocksize = desc->maxiv;
113 s->prev = (uint8_t *)s + sizeof(kripto_stream);
115 /* block cipher */
116 s->block = kripto_block_create(EXT(desc)->block, rounds, key, key_len);
117 if(!s->block)
119 kripto_memwipe(s, sizeof(kripto_stream) + s->blocksize);
120 free(s);
121 return 0;
124 /* IV */
125 if(iv_len) memcpy(s->prev, iv, iv_len);
126 memset(s->prev + iv_len, 0, s->blocksize - iv_len);
128 return s;
131 static kripto_stream *ofb_recreate
133 kripto_stream *s,
134 unsigned int rounds,
135 const void *key,
136 unsigned int key_len,
137 const void *iv,
138 unsigned int iv_len
141 /* block cipher */
142 s->block = kripto_block_recreate(s->block, rounds, key, key_len);
143 if(!s->block)
145 kripto_memwipe(s, sizeof(kripto_stream) + s->blocksize);
146 free(s);
147 return 0;
150 /* IV */
151 if(iv_len) memcpy(s->prev, iv, iv_len);
152 memset(s->prev + iv_len, 0, s->blocksize - iv_len);
154 s->used = s->blocksize;
156 return s;
159 kripto_stream_desc *kripto_stream_ofb(const kripto_block_desc *block)
161 struct ext *s;
163 s = malloc(sizeof(struct ext));
164 if(!s) return 0;
166 s->block = block;
168 s->desc.create = &ofb_create;
169 s->desc.recreate = &ofb_recreate;
170 s->desc.encrypt = &ofb_crypt;
171 s->desc.decrypt = &ofb_crypt;
172 s->desc.prng = &ofb_prng;
173 s->desc.destroy = &ofb_destroy;
174 s->desc.multof = 1;
175 s->desc.maxkey = kripto_block_maxkey(block);
176 s->desc.maxiv = kripto_block_size(block);
178 return (kripto_stream_desc *)s;