#include #include #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); }