X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/076bb54e68477f883033bee696c9c5f801ece2f2..094ca922beda8a0af97cf9aeeeea3a983b59531c:/transform.c diff --git a/transform.c b/transform.c index 8fdf9fd..281e667 100644 --- a/transform.c +++ b/transform.c @@ -13,6 +13,7 @@ #include "util.h" #include "serpent.h" #include "unaligned.h" +#include "hexdebug.h" /* Required key length in bytes */ #define REQUIRED_KEYLEN ((512+64+32)/8) @@ -49,25 +50,30 @@ static bool_t transform_setkey(void *sst, uint8_t *key, int32_t keylen) #if 0 { - int i; printf("Setting key to: "); - for (i=0; icryptkey,256,key); - serpent_makekey(&ti->mackey,256,key+32); - ti->cryptiv=GET_32BIT_MSB_FIRST(key+64); - ti->maciv=GET_32BIT_MSB_FIRST(key+68); - ti->sendseq=GET_32BIT_MSB_FIRST(key+72); + serpentbe_makekey(&ti->cryptkey,256,key); + serpentbe_makekey(&ti->mackey,256,key+32); + ti->cryptiv=get_uint32(key+64); + ti->maciv=get_uint32(key+68); + ti->sendseq=get_uint32(key+72); ti->lastrecvseq=ti->sendseq; ti->keyed=True; return True; } +static bool_t transform_valid(void *sst) +{ + struct transform_inst *ti=sst; + + return ti->keyed; +} + static void transform_delkey(void *sst) { struct transform_inst *ti=sst; @@ -114,8 +120,8 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf, it we've have to add 16 bytes to each message, not 4, so that the message stays a multiple of 16 bytes long.) */ memset(iv,0,16); - PUT_32BIT_MSB_FIRST(iv, ti->maciv); - serpent_encrypt(&ti->mackey,iv,macacc); + put_uint32(iv, ti->maciv); + serpentbe_encrypt(&ti->mackey,iv,macacc); /* CBCMAC: encrypt in CBC mode. The MAC is the last encrypted block encrypted once again. */ @@ -123,16 +129,16 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf, { for (i = 0; i < 16; i++) macplain[i] = macacc[i] ^ n[i]; - serpent_encrypt(&ti->mackey,macplain,macacc); + serpentbe_encrypt(&ti->mackey,macplain,macacc); } - serpent_encrypt(&ti->mackey,macacc,macacc); + serpentbe_encrypt(&ti->mackey,macacc,macacc); memcpy(buf_append(buf,16),macacc,16); /* Serpent-CBC. We expand the ID as for CBCMAC, do the encryption, and prepend the IV before increasing it. */ memset(iv,0,16); - PUT_32BIT_MSB_FIRST(iv, ti->cryptiv); - serpent_encrypt(&ti->cryptkey,iv,iv); + put_uint32(iv, ti->cryptiv); + serpentbe_encrypt(&ti->cryptkey,iv,iv); /* CBC: each block is XORed with the previous encrypted block (or the IV) before being encrypted. */ @@ -142,7 +148,7 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf, { for (i = 0; i < 16; i++) n[i] ^= p[i]; - serpent_encrypt(&ti->cryptkey,n,n); + serpentbe_encrypt(&ti->cryptkey,n,n); p=n; } @@ -171,23 +177,28 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf, return 1; } + if (buf->size < 4 + 16 + 16) { + *errmsg="msg too short"; + return 1; + } /* CBC */ memset(iv,0,16); { uint32_t ivword = buf_unprepend_uint32(buf); - PUT_32BIT_MSB_FIRST(iv, ivword); + put_uint32(iv, ivword); } /* Assert bufsize is multiple of blocksize */ if (buf->size&0xf) { *errmsg="msg not multiple of cipher blocksize"; + return 1; } - serpent_encrypt(&ti->cryptkey,iv,iv); + serpentbe_encrypt(&ti->cryptkey,iv,iv); for (n=buf->start; nstart+buf->size; n+=16) { for (i = 0; i < 16; i++) pct[i] = n[i]; - serpent_decrypt(&ti->cryptkey,n,n); + serpentbe_decrypt(&ti->cryptkey,n,n); for (i = 0; i < 16; i++) n[i] ^= iv[i]; memcpy(iv, pct, 16); @@ -196,8 +207,8 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf, /* CBCMAC */ macexpected=buf_unappend(buf,16); memset(iv,0,16); - PUT_32BIT_MSB_FIRST(iv, ti->maciv); - serpent_encrypt(&ti->mackey,iv,macacc); + put_uint32(iv, ti->maciv); + serpentbe_encrypt(&ti->mackey,iv,macacc); /* CBCMAC: encrypt in CBC mode. The MAC is the last encrypted block encrypted once again. */ @@ -205,10 +216,10 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf, { for (i = 0; i < 16; i++) macplain[i] = macacc[i] ^ n[i]; - serpent_encrypt(&ti->mackey,macplain,macacc); + serpentbe_encrypt(&ti->mackey,macplain,macacc); } - serpent_encrypt(&ti->mackey,macacc,macacc); - if (memcmp(macexpected,macacc,16)!=0) { + serpentbe_encrypt(&ti->mackey,macacc,macacc); + if (!consttime_memeq(macexpected,macacc,16)!=0) { *errmsg="invalid MAC"; return 1; } @@ -222,13 +233,7 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf, return 1; } - padp=buf_unappend(buf,padlen-1); - for (i=0; iops.st=ti; ti->ops.setkey=transform_setkey; + ti->ops.valid=transform_valid; ti->ops.delkey=transform_delkey; ti->ops.forwards=transform_forward; ti->ops.reverse=transform_reverse; @@ -320,8 +326,9 @@ void transform_module(dict_t *dict) /* * Serpent self-test. * - * This test pattern is taken directly from the Serpent test - * vectors, to ensure we have all endianness issues correct. -sgt + * This test pattern was taken directly from the Serpent test + * vectors, which results in a big-endian Serpent which is not + * compatible with other implementations. */ /* Serpent self-test */ @@ -329,18 +336,18 @@ void transform_module(dict_t *dict) "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" "\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00", 32); - serpent_makekey(&k,256,data); + serpentbe_makekey(&k,256,data); memcpy(plaintext, "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10", 16); - serpent_encrypt(&k,plaintext,ciphertext); + serpentbe_encrypt(&k,plaintext,ciphertext); if (memcmp(ciphertext, "\xca\x7f\xa1\x93\xe3\xeb\x9e\x99" "\xbd\x87\xe3\xaf\x3c\x9a\xdf\x93", 16)) { fatal("transform_module: serpent failed self-test (encrypt)"); } - serpent_decrypt(&k,ciphertext,plaintext); + serpentbe_decrypt(&k,ciphertext,plaintext); if (memcmp(plaintext, "\x01\x23\x45\x67\x89\xab\xcd\xef" "\xfe\xdc\xba\x98\x76\x54\x32\x10", 16)) { fatal("transform_module: serpent failed self-test (decrypt)");