diff options
author | Jérémy Zurcher <jeremy@asynk.ch> | 2010-07-09 12:32:17 +0200 |
---|---|---|
committer | Jérémy Zurcher <jeremy@asynk.ch> | 2010-07-09 12:32:17 +0200 |
commit | 6c027b4de25a529908be895e7ff19236f4002a57 (patch) | |
tree | f70d3a400bbb9ba8a83e9d4ffcaa4b6e367fc8bb /crypto_buffer_put.c | |
download | crypto-6c027b4de25a529908be895e7ff19236f4002a57.zip crypto-6c027b4de25a529908be895e7ff19236f4002a57.tar.gz |
initial commit, resurrect one of my realy old projects
Diffstat (limited to 'crypto_buffer_put.c')
-rw-r--r-- | crypto_buffer_put.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/crypto_buffer_put.c b/crypto_buffer_put.c new file mode 100644 index 0000000..74f30a0 --- /dev/null +++ b/crypto_buffer_put.c @@ -0,0 +1,112 @@ +#include <errno.h> +#include <string.h> + +#include "crypto_buffer.h" + + +/* s->data_st must have been set */ +/* after this s->e_ptr is updated */ +static int allwrite(crypto_buffer *s) +{ + u8 *buffer; + int w, bytes; + + buffer = s->e_buffer; + bytes = s->data_st.bytes + (s->block_size << 1); + s->cipher(&s->ctx,(u8*)s->e_data,(u8*)&s->data_st); + while (bytes) { + w = s->op(s->fd,buffer,bytes); + if (w == -1) { + if (errno == EINTR) continue; + return -1; /* note that some data may have been written */ + } + if (w == 0) ; /* luser's fault */ + buffer += w; + bytes -= w; + } + s->e_ptr = (u8*)s->e_data + s->block_size; + return 0; +} + + +/* after this s->e_ptr and s->c_ptr are updated */ +int crypto_buffer_flush(crypto_buffer *s) +{ + register u32 len, len2; + register u8* e_ptr; + + len = s->e_len; + e_ptr = s->e_ptr; + if(e_ptr == s->e_end) { + s->data_st.bytes = s->data_st.strlen = len; + if (allwrite(s) == -1) return -1; + e_ptr = s->e_ptr; + } + len2 = len = e_ptr + s->e_len - s->e_end; /* used bytes in e_buffer */ + if(s->c_ptr != s->c_buffer){ + s->cipher(&s->ctx, e_ptr, s->c_buffer); + len += s->block_size; + len2 += s->c_ptr - s->c_buffer; + } + s->data_st.bytes = len; + s->data_st.strlen = len2; + if (allwrite(s) == -1) return -1; + s->c_ptr = s->c_buffer; + return 0; +} + +int crypto_buffer_put(crypto_buffer *s,const u8 *buf,u32 len) +{ + register u32 size; + register u8* e_ptr; + register u8* e_end; + u32 free; + + free = s->c_end - s->c_ptr; + if (len > free) { + if(free){ + memcpy(s->c_ptr, buf, free); + buf += free; + len -= free; + } + /* now c_buffer is full */ + e_ptr = s->e_ptr; + e_end = s->e_end; + size = s->block_size; + if(e_ptr == e_end) { + /* e_buffer full */ + s->data_st.bytes = s->data_st.strlen = s->e_len; + if (allwrite(s) == -1) return -1; + e_ptr = s->e_ptr; + } + s->cipher(&s->ctx, e_ptr, s->c_buffer); + e_ptr += size; + s->c_ptr = s->c_buffer; + /* now c_buffer is empty */ + while(len > size){ + if(e_ptr == e_end) { + s->data_st.bytes = s->data_st.strlen = s->e_len; + if (allwrite(s) == -1) return -1; + e_ptr = s->e_ptr; + } + s->cipher(&s->ctx, e_ptr, buf); + e_ptr += size; + buf += size; + len -= size; + } + /* don't forget */ + s->e_ptr = e_ptr; + } + /* now len < s->block_size + s->c_buffer - s->c_ptr */ + if(len){ + memcpy(s->c_ptr, buf, len); + s->c_ptr += len; + } + return 0; +} + +int crypto_buffer_putflush(crypto_buffer *s,const u8 *buf,u32 len) +{ + if (crypto_buffer_put(s, buf, len) == -1) return -1; + return crypto_buffer_flush(s); +} |