/** * buffers.c * Buffers. * * Matej Pfajfar <mp292@cam.ac.uk> */ /* * Changes : * $Log$ * Revision 1.1 2002/06/26 22:45:50 arma * Initial revision * * Revision 1.1 2002/04/02 14:28:01 badbytes * Final finishes. * */ #include <unistd.h> #include <openssl/evp.h> #include "../common/cell.h" #include "../common/log.h" #include "buffers.h" #include "crypto.h" #include "op.h" int buffer_data(uint16_t aci, unsigned char *buf, size_t buflen, unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, crypt_path_t **cpath, size_t cpathlen) { int retval; int i; cell_t *cellbuf; cell_t *c; size_t cellbuflen; size_t cells; unsigned char *tmpbuf; /* temporary buffer for realloc() operations */ if (!buf || !outbuf || !outbuflen) /* invalid parameters */ return -1; /* split the plaintext into DATA cells */ retval = pack_data(aci,buf, buflen, (unsigned char **)&cellbuf, &cellbuflen); if (retval == -1) { log(LOG_DEBUG,"buffer_data() : Could not pack data into cells."); return -1; } log(LOG_DEBUG,"buffer_data() : DATA cells created."); cells = cellbuflen/(sizeof(cell_t)); /* encrypt the cells */ for (i=0; i<cells; i++) { c = cellbuf+i; /* encrypt the payload length */ retval = crypt_f((unsigned char *)&c->length, 1, cpath, cpathlen); if (retval == -1) { log(LOG_ERR,"Could not encrypt the payload length of a DATA cell."); free((void *)cellbuf); return -1; } /* encrypt the payload */ retval = crypt_f((unsigned char *)c->payload, CELL_PAYLOAD_SIZE, cpath, cpathlen); if (retval == -1) { log(LOG_ERR,"Could not encrypt the payload of a DATA cell."); free((void *)cellbuf); return -1; } } /* now copy the cells into the output buffer */ if (*outbuflen-*outbuf_dataoffset-*outbuf_datalen < cellbuflen) /* increase the buffer size if necessary */ { /* allocate a new buffer (in OP_DEFAULT_BUFSIZE chunks)*/ tmpbuf = (unsigned char *)malloc(((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1)*OP_DEFAULT_BUFSIZE); if (!tmpbuf) { log(LOG_ERR,"Error allocating memory."); free((void *)cellbuf); return -1; } /* copy old data to the new buffer */ memcpy((void *)tmpbuf,(void *)(*outbuf+*outbuf_dataoffset),*outbuf_datalen); /* replace the old buffer with the new one */ if (*outbuf) free((void *)*outbuf); *outbuf = tmpbuf; *outbuflen = ((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1) * OP_DEFAULT_BUFSIZE; *outbuf_dataoffset = 0; } memcpy((void *)(*outbuf + *outbuf_dataoffset + *outbuf_datalen), (void *)cellbuf, cellbuflen); *outbuf_datalen += cellbuflen; return 0; } int buffer_create(uint16_t aci, unsigned char *onion, size_t onionlen, unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, crypt_path_t **cpath, size_t cpathlen) { int retval; cell_t *cellbuf; size_t cells; size_t cellbuflen; unsigned char *tmpbuf; /* temporary buffer for realloc() operations */ if (!onion || !outbuf || !outbuflen || !outbuf_dataoffset || !outbuf_datalen) /* invalid parameters */ return -1; retval = pack_create(aci,onion, onionlen, (unsigned char **)&cellbuf, &cellbuflen); if (retval == -1) { log(LOG_DEBUG,"buffer_create() : Could not pack the onion into cells."); return -1; } log(LOG_DEBUG,"buffer_create() : CREATE cells created."); cells = cellbuflen/(sizeof(cell_t)); /* now copy the cells into the output buffer */ if (*outbuflen-*outbuf_dataoffset-*outbuf_datalen < cellbuflen) /* increase the buffer size if necessary */ { /* allocate a new buffer (in OP_DEFAULT_BUFSIZE chunks)*/ tmpbuf = (unsigned char *)malloc(((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1)*OP_DEFAULT_BUFSIZE); if (!tmpbuf) { log(LOG_ERR,"Error allocating memory."); free((void *)cellbuf); return -1; } /* copy old data to the new buffer */ memcpy((void *)tmpbuf,(void *)(*outbuf+*outbuf_dataoffset),*outbuf_datalen); /* replace the old buffer with the new one */ if (*outbuf) free((void *)*outbuf); *outbuf = tmpbuf; *outbuflen = ((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1) * OP_DEFAULT_BUFSIZE; *outbuf_dataoffset = 0; } memcpy((void *)(*outbuf + *outbuf_dataoffset + *outbuf_datalen), (void *)cellbuf, cellbuflen); *outbuf_datalen += cellbuflen; return 0; }