#include "util.h"
#include "serpent.h"
#include "unaligned.h"
+#include "hexdebug.h"
/* Required key length in bytes */
#define REQUIRED_KEYLEN ((512+64+32)/8)
#if 0
{
- int i;
printf("Setting key to: ");
- for (i=0; i<keylen; i++)
- printf("%02x",key[i]);
+ hexdebug(stdout,key,keylen);
printf("\n");
}
#endif /* 0 */
- serpent_makekey(&ti->cryptkey,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;
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. */
{
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. */
{
for (i = 0; i < 16; i++)
n[i] ^= p[i];
- serpent_encrypt(&ti->cryptkey,n,n);
+ serpentbe_encrypt(&ti->cryptkey,n,n);
p=n;
}
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; n<buf->start+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);
/* 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. */
{
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;
}
return 1;
}
- padp=buf_unappend(buf,padlen-1);
- for (i=0; i<padlen-1; i++) {
- if (*++padp != padlen) {
- *errmsg="pkcs5: corrupted padding";
- return 1;
- }
- }
+ buf_unappend(buf,padlen-1);
/* Sequence number must be within max_skew of lastrecvseq; lastrecvseq
is only allowed to increase. */
ti->ops.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;
/*
* 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 */
"\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)");