CFB buffering
[rofl0r-kripto.git] / lib / mode / ofb.c
blob2e914c60599cbe1058f17df9a7f89af4d8b8237a
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/macros.h>
20 #include <kripto/memwipe.h>
21 #include <kripto/block.h>
22 #include <kripto/mode.h>
23 #include <kripto/mode_desc.h>
24 #include <kripto/stream.h>
25 #include <kripto/stream_desc.h>
27 #include <kripto/mode/ofb.h>
29 struct kripto_stream
31 kripto_stream_desc *desc;
32 const kripto_block *block;
33 uint8_t *prev;
34 unsigned int block_size;
35 unsigned int used;
38 static size_t ofb_crypt
40 kripto_stream *s,
41 const void *in,
42 void *out,
43 const size_t len
46 size_t i;
48 for(i = 0; i < len; i++)
50 if(s->used == s->block_size)
52 kripto_block_encrypt(s->block, s->prev, s->prev);
53 s->used = 0;
56 U8(out)[i] = CU8(in)[i] ^ s->prev[s->used++];
59 return i;
62 static size_t ofb_prng
64 kripto_stream *s,
65 void *out,
66 const size_t len
69 size_t i;
71 for(i = 0; i < len; i++)
73 if(s->used == s->block_size)
75 kripto_block_encrypt(s->block, s->prev, s->prev);
76 s->used = 0;
79 U8(out)[i] = s->prev[s->used++];
82 return i;
85 static void ofb_destroy(kripto_stream *s)
87 kripto_memwipe(s, sizeof(struct kripto_stream)
88 + sizeof(struct kripto_stream_desc)
89 + s->block_size
92 free(s);
95 static kripto_stream *ofb_create
97 const kripto_block *block,
98 const void *iv,
99 const unsigned int iv_len
102 kripto_stream *s;
103 kripto_block_desc *b;
104 struct kripto_stream_desc *stream;
106 b = kripto_block_get_desc(block);
108 s = malloc(sizeof(struct kripto_stream)
109 + sizeof(struct kripto_stream_desc)
110 + kripto_block_size(b)
112 if(!s) return 0;
114 s->block_size = kripto_block_size(b);
116 stream = (struct kripto_stream_desc *)
117 ((uint8_t *)s + sizeof(struct kripto_stream));
119 s->prev = (uint8_t *)stream + sizeof(struct kripto_stream_desc);
121 stream->encrypt = &ofb_crypt;
122 stream->decrypt = &ofb_crypt;
123 stream->prng = &ofb_prng;
124 stream->create = 0;
125 stream->destroy = &ofb_destroy;
126 stream->max_key = kripto_block_max_key(b);
127 stream->max_iv = s->block_size;
129 s->desc = stream;
131 if(iv_len) memcpy(s->prev, iv, iv_len);
132 memset(s->prev + iv_len, 0, s->block_size - iv_len);
134 s->used = s->block_size;
135 s->block = block;
137 return s;
140 static const struct kripto_mode_desc ofb =
142 &ofb_create,
143 &kripto_block_size
146 kripto_mode_desc *const kripto_mode_ofb = &ofb;