aboutsummaryrefslogtreecommitdiff
path: root/src/common/aes.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-02-07 16:10:33 +0000
committerNick Mathewson <nickm@torproject.org>2008-02-07 16:10:33 +0000
commiteecc44dab8ad98246b2c4dbedf977113f1874f77 (patch)
treed1b52922bb8a1d03919bf0422ab2ea5e320e0ad3 /src/common/aes.c
parent842a33ff20f1da87d64ae3922eab135dc37bde16 (diff)
downloadtor-eecc44dab8ad98246b2c4dbedf977113f1874f77.tar
tor-eecc44dab8ad98246b2c4dbedf977113f1874f77.tar.gz
r17963@catbus: nickm | 2008-02-07 10:14:25 -0500
Be more thorough about memory poisoning and clearing. Add an in-place version of aes_crypt in order to remove a memcpy from relay_crypt_one_payload. svn:r13414
Diffstat (limited to 'src/common/aes.c')
-rw-r--r--src/common/aes.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/common/aes.c b/src/common/aes.c
index 6dc489698..cd8317dd1 100644
--- a/src/common/aes.c
+++ b/src/common/aes.c
@@ -289,7 +289,7 @@ aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
* of alignmement, using a bigger buffer, and so on. Not till after 0.1.2.x,
* though. */
int c = cipher->pos;
- if (!len) return;
+ if (PREDICT_UNLIKELY(!len)) return;
while (1) {
do {
@@ -312,6 +312,42 @@ aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
}
}
+/** Encrypt <b>len</b> bytes from <b>input</b>, storing the results in place.
+ * Uses the key in <b>cipher</b>, and advances the counter by <b>len</b> bytes
+ * as it encrypts.
+ */
+void
+aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
+{
+
+ /* XXXX This function is up to 5% of our runtime in some profiles;
+ * we should look into unrolling some of the loops; taking advantage
+ * of alignmement, using a bigger buffer, and so on. Not till after 0.1.2.x,
+ * though. */
+ int c = cipher->pos;
+ if (PREDICT_UNLIKELY(!len)) return;
+
+ while (1) {
+ do {
+ if (len-- == 0) { cipher->pos = c; return; }
+ *(data++) ^= cipher->buf[c];
+ } while (++c != 16);
+ cipher->pos = c = 0;
+ if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
+ if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
+ if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
+ ++COUNTER(cipher, 3);
+ UPDATE_CTR_BUF(cipher, 3);
+ }
+ UPDATE_CTR_BUF(cipher, 2);
+ }
+ UPDATE_CTR_BUF(cipher, 1);
+ }
+ UPDATE_CTR_BUF(cipher, 0);
+ _aes_fill_buf(cipher);
+ }
+}
+
/** Reset the 128-bit counter of <b>cipher</b> to the 16-bit big-endian value
* in <b>iv</b>. */
void