summaryrefslogtreecommitdiff
path: root/pjlib-util
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-05-12 08:01:56 +0000
committerBenny Prijono <bennylp@teluu.com>2009-05-12 08:01:56 +0000
commit844e5ae0b40d77df6a0038d0b10d3f6b49921d8d (patch)
tree0572c38f92a076b1ab91abb90939698dde38b8c7 /pjlib-util
parent9b44046fa7b5880d907374b737998434d625c42b (diff)
Fixed ticket #836: SHA1 encryption may corrupt STUN packets with MESSAGE-INTEGRITY. Also added unit test to verify this behavior
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2690 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib-util')
-rw-r--r--pjlib-util/src/pjlib-util-test/encryption.c31
-rw-r--r--pjlib-util/src/pjlib-util/sha1.c10
2 files changed, 36 insertions, 5 deletions
diff --git a/pjlib-util/src/pjlib-util-test/encryption.c b/pjlib-util/src/pjlib-util-test/encryption.c
index c31bea95..3db0d9a0 100644
--- a/pjlib-util/src/pjlib-util-test/encryption.c
+++ b/pjlib-util/src/pjlib-util-test/encryption.c
@@ -64,10 +64,13 @@ static void digest_to_hex(const pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE],
static int sha1_test1(void)
{
+ enum { MILLION = 1000000 };
int k;
pj_sha1_context context;
pj_uint8_t digest[20];
char output[80];
+ pj_pool_t *pool;
+ pj_uint8_t *block;
PJ_LOG(3, (THIS_FILE, " SHA1 test vector 1 from sha1.c.."));
@@ -86,7 +89,7 @@ static int sha1_test1(void)
/* million 'a' vector we feed separately */
pj_sha1_init(&context);
- for (k = 0; k < 1000000; k++)
+ for (k = 0; k < MILLION; k++)
pj_sha1_update(&context, (pj_uint8_t*)"a", 1);
pj_sha1_final(&context, digest);
digest_to_hex(digest, output);
@@ -95,6 +98,32 @@ static int sha1_test1(void)
return -20;
}
+ /* million 'a' test, using block */
+ pool = pj_pool_create(mem, "sha1test", 256, 512, NULL);
+ block = (pj_uint8_t*)pj_pool_alloc(pool, MILLION);
+ pj_memset(block, 'a', MILLION);
+
+ pj_sha1_init(&context);
+ pj_sha1_update(&context, block, MILLION);
+ pj_sha1_final(&context, digest);
+ digest_to_hex(digest, output);
+ if (strcmp(output, sha1_test_results[2])) {
+ pj_pool_release(pool);
+ PJ_LOG(3, (THIS_FILE, " incorrect hash result for block update!"));
+ return -21;
+ }
+
+ /* verify that original buffer was not modified */
+ for (k=0; k<MILLION; ++k) {
+ if (block[k] != 'a') {
+ pj_pool_release(pool);
+ PJ_LOG(3, (THIS_FILE, " block was modified!"));
+ return -22;
+ }
+ }
+
+ pj_pool_release(pool);
+
/* success */
return(0);
}
diff --git a/pjlib-util/src/pjlib-util/sha1.c b/pjlib-util/src/pjlib-util/sha1.c
index deb75162..afdbff2d 100644
--- a/pjlib-util/src/pjlib-util/sha1.c
+++ b/pjlib-util/src/pjlib-util/sha1.c
@@ -105,7 +105,7 @@ A million repetitions of "a"
#undef SHA1HANDSOFF
-static void SHA1_Transform(pj_uint32_t state[5], const pj_uint8_t buffer[64]);
+static void SHA1_Transform(pj_uint32_t state[5], pj_uint8_t buffer[64]);
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
@@ -131,7 +131,7 @@ static void SHA1_Transform(pj_uint32_t state[5], const pj_uint8_t buffer[64]);
/* Hash a single 512-bit block. This is the core of the algorithm. */
-static void SHA1_Transform(pj_uint32_t state[5], const pj_uint8_t buffer[64])
+static void SHA1_Transform(pj_uint32_t state[5], pj_uint8_t buffer[64])
{
pj_uint32_t a, b, c, d, e;
typedef union {
@@ -214,8 +214,10 @@ PJ_DEF(void) pj_sha1_update(pj_sha1_context* context,
if ((j + len) > 63) {
pj_memcpy(&context->buffer[j], data, (i = 64-j));
SHA1_Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1_Transform(context->state, data + i);
+ for ( ; i + 63 < len; i += 64) {
+ pj_uint8_t tmp[64];
+ pj_memcpy(tmp, data + i, 64);
+ SHA1_Transform(context->state, tmp);
}
j = 0;
}