modes cleaned and CFB mode added (not tested)
[rofl0r-kripto.git] / lib / mode / ctr.c
blobabe825fd6402808166974fdcb3a2a0857d7bd6f2
1 /*
2 * Copyright (C) 2011 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/ctr.h>
29 struct kripto_stream
31 kripto_stream_desc *desc;
32 const kripto_block *block;
33 unsigned int block_size;
34 uint8_t *x;
35 uint8_t *buf;
36 unsigned int used;
39 static size_t ctr_crypt
41 kripto_stream *s,
42 const void *in,
43 void *out,
44 const size_t len
47 size_t i;
48 unsigned int n;
50 for(i = 0; i < len; i++)
52 if(s->used == s->block_size)
54 kripto_block_encrypt(s->block, s->x, s->buf);
55 s->used = 0;
57 for(n = s->block_size - 1; n; n--)
58 if(++s->x[n]) break;
61 U8(out)[i] = CU8(in)[i] ^ s->buf[s->used++];
64 return i;
67 static size_t ctr_prng
69 kripto_stream *s,
70 void *out,
71 const size_t len
74 size_t i;
75 unsigned int n;
77 for(i = 0; i < len; i++)
79 if(s->used == s->block_size)
81 kripto_block_encrypt(s->block, s->x, s->buf);
82 s->used = 0;
84 for(n = s->block_size - 1; n; n--)
85 if(++s->x[n]) break;
88 U8(out)[i] = s->buf[s->used++];
91 return i;
94 static void ctr_destroy(kripto_stream *s)
96 kripto_memwipe(s, sizeof(kripto_stream)
97 + (s->block_size << 1)
98 + sizeof(kripto_stream_desc)
101 free(s);
104 static kripto_stream *ctr_create
106 const kripto_block *block,
107 const void *iv,
108 const unsigned int iv_len
111 kripto_stream *s;
112 kripto_block_desc *b;
113 struct kripto_stream_desc *stream;
115 b = kripto_block_get_desc(block);
117 s = malloc(sizeof(kripto_stream)
118 + (kripto_block_size(b) << 1)
119 + sizeof(kripto_stream_desc)
121 if(!s) return 0;
123 s->block_size = kripto_block_size(b);
125 stream = (struct kripto_stream_desc *)
126 ((uint8_t *)s + sizeof(kripto_stream));
128 s->x = (uint8_t *)stream + sizeof(kripto_stream_desc);
129 s->buf = s->x + s->block_size;
131 stream->encrypt = &ctr_crypt;
132 stream->decrypt = &ctr_crypt;
133 stream->prng = &ctr_prng;
134 stream->create = 0;
135 stream->destroy = &ctr_destroy;
136 stream->max_key = kripto_block_max_key(b);
137 stream->max_iv = s->block_size;
139 s->desc = stream;
141 if(iv_len) memcpy(s->x, iv, iv_len);
142 memset(s->x + iv_len, 0, s->block_size - iv_len);
144 s->used = s->block_size;
145 s->block = block;
147 return s;
150 static const struct kripto_mode_desc ctr =
152 &ctr_create,
153 &kripto_block_size
156 kripto_mode_desc *const kripto_mode_ctr = &ctr;