buffers.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * buffers.c
  3. * Buffers.
  4. *
  5. * Matej Pfajfar <mp292@cam.ac.uk>
  6. */
  7. /*
  8. * Changes :
  9. * $Log$
  10. * Revision 1.1 2002/06/26 22:45:50 arma
  11. * Initial revision
  12. *
  13. * Revision 1.1 2002/04/02 14:28:01 badbytes
  14. * Final finishes.
  15. *
  16. */
  17. #include <unistd.h>
  18. #include <openssl/evp.h>
  19. #include "../common/cell.h"
  20. #include "../common/log.h"
  21. #include "buffers.h"
  22. #include "crypto.h"
  23. #include "op.h"
  24. 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)
  25. {
  26. int retval;
  27. int i;
  28. cell_t *cellbuf;
  29. cell_t *c;
  30. size_t cellbuflen;
  31. size_t cells;
  32. unsigned char *tmpbuf; /* temporary buffer for realloc() operations */
  33. if (!buf || !outbuf || !outbuflen) /* invalid parameters */
  34. return -1;
  35. /* split the plaintext into DATA cells */
  36. retval = pack_data(aci,buf, buflen, (unsigned char **)&cellbuf, &cellbuflen);
  37. if (retval == -1)
  38. {
  39. log(LOG_DEBUG,"buffer_data() : Could not pack data into cells.");
  40. return -1;
  41. }
  42. log(LOG_DEBUG,"buffer_data() : DATA cells created.");
  43. cells = cellbuflen/(sizeof(cell_t));
  44. /* encrypt the cells */
  45. for (i=0; i<cells; i++)
  46. {
  47. c = cellbuf+i;
  48. /* encrypt the payload length */
  49. retval = crypt_f((unsigned char *)&c->length, 1, cpath, cpathlen);
  50. if (retval == -1)
  51. {
  52. log(LOG_ERR,"Could not encrypt the payload length of a DATA cell.");
  53. free((void *)cellbuf);
  54. return -1;
  55. }
  56. /* encrypt the payload */
  57. retval = crypt_f((unsigned char *)c->payload, CELL_PAYLOAD_SIZE, cpath, cpathlen);
  58. if (retval == -1)
  59. {
  60. log(LOG_ERR,"Could not encrypt the payload of a DATA cell.");
  61. free((void *)cellbuf);
  62. return -1;
  63. }
  64. }
  65. /* now copy the cells into the output buffer */
  66. if (*outbuflen-*outbuf_dataoffset-*outbuf_datalen < cellbuflen) /* increase the buffer size if necessary */
  67. {
  68. /* allocate a new buffer (in OP_DEFAULT_BUFSIZE chunks)*/
  69. tmpbuf = (unsigned char *)malloc(((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1)*OP_DEFAULT_BUFSIZE);
  70. if (!tmpbuf)
  71. {
  72. log(LOG_ERR,"Error allocating memory.");
  73. free((void *)cellbuf);
  74. return -1;
  75. }
  76. /* copy old data to the new buffer */
  77. memcpy((void *)tmpbuf,(void *)(*outbuf+*outbuf_dataoffset),*outbuf_datalen);
  78. /* replace the old buffer with the new one */
  79. if (*outbuf)
  80. free((void *)*outbuf);
  81. *outbuf = tmpbuf;
  82. *outbuflen = ((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1) * OP_DEFAULT_BUFSIZE;
  83. *outbuf_dataoffset = 0;
  84. }
  85. memcpy((void *)(*outbuf + *outbuf_dataoffset + *outbuf_datalen), (void *)cellbuf, cellbuflen);
  86. *outbuf_datalen += cellbuflen;
  87. return 0;
  88. }
  89. 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)
  90. {
  91. int retval;
  92. cell_t *cellbuf;
  93. size_t cells;
  94. size_t cellbuflen;
  95. unsigned char *tmpbuf; /* temporary buffer for realloc() operations */
  96. if (!onion || !outbuf || !outbuflen || !outbuf_dataoffset || !outbuf_datalen) /* invalid parameters */
  97. return -1;
  98. retval = pack_create(aci,onion, onionlen, (unsigned char **)&cellbuf, &cellbuflen);
  99. if (retval == -1)
  100. {
  101. log(LOG_DEBUG,"buffer_create() : Could not pack the onion into cells.");
  102. return -1;
  103. }
  104. log(LOG_DEBUG,"buffer_create() : CREATE cells created.");
  105. cells = cellbuflen/(sizeof(cell_t));
  106. /* now copy the cells into the output buffer */
  107. if (*outbuflen-*outbuf_dataoffset-*outbuf_datalen < cellbuflen) /* increase the buffer size if necessary */
  108. {
  109. /* allocate a new buffer (in OP_DEFAULT_BUFSIZE chunks)*/
  110. tmpbuf = (unsigned char *)malloc(((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1)*OP_DEFAULT_BUFSIZE);
  111. if (!tmpbuf)
  112. {
  113. log(LOG_ERR,"Error allocating memory.");
  114. free((void *)cellbuf);
  115. return -1;
  116. }
  117. /* copy old data to the new buffer */
  118. memcpy((void *)tmpbuf,(void *)(*outbuf+*outbuf_dataoffset),*outbuf_datalen);
  119. /* replace the old buffer with the new one */
  120. if (*outbuf)
  121. free((void *)*outbuf);
  122. *outbuf = tmpbuf;
  123. *outbuflen = ((cellbuflen+*outbuf_datalen)/OP_DEFAULT_BUFSIZE+1) * OP_DEFAULT_BUFSIZE;
  124. *outbuf_dataoffset = 0;
  125. }
  126. memcpy((void *)(*outbuf + *outbuf_dataoffset + *outbuf_datalen), (void *)cellbuf, cellbuflen);
  127. *outbuf_datalen += cellbuflen;
  128. return 0;
  129. }