diff --git a/crypto/serpent/serpent.c b/crypto/serpent/serpent.c index 9943c49d..29e486f6 100644 --- a/crypto/serpent/serpent.c +++ b/crypto/serpent/serpent.c @@ -74,25 +74,25 @@ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include -void serpent_whiten(serpent_blk *dst, serpent_key_t *src, int idx) { +static void serpent_whiten(serpent_blk *dst, serpent_key_t *src, int idx) { uint8_t i; serpent_blk *p = (serpent_blk*)&src->x[idx]; - for (i = 0; iw[i] ^= p->w[i]; } } -void permute(serpent_blk *out, - serpent_blk *in, int type) +static void permute(serpent_blk *out, serpent_blk *in, int type) { uint8_t cy; uint8_t n, m; - for (n = 0; nw[n] = 0; } @@ -120,13 +120,13 @@ void permute(serpent_blk *out, #define HI_NIBBLE(b) (((b) >> 4) & 0x0F) #define LO_NIBBLE(b) ((b) & 0x0F) -uint32_t serpent_gen_w(uint32_t *b, uint32_t i) { +static uint32_t serpent_gen_w(uint32_t *b, uint32_t i) { uint32_t ret; ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ i; return ROTL32(ret, 11); } -void serpent_subbytes(serpent_blk *blk, uint32_t box_idx, int type) +static void serpent_subbytes(serpent_blk *blk, uint32_t box_idx, int type) { serpent_blk tmp_blk, sb; uint8_t *sbp; @@ -171,18 +171,18 @@ void serpent_subbytes(serpent_blk *blk, uint32_t box_idx, int type) permute(&tmp_blk, blk, SERPENT_IP); - for (i = 0; iw[0]; x1 = x->w[1]; x2 = x->w[2]; @@ -210,7 +210,7 @@ void serpent_lt(serpent_blk* x, int enc) x0 ^= x1 ^ x3; x2 ^= x3 ^ (x1 << 7); x0 = ROTL32(x0, 5); - x2 = ROTR32(x2, 10); + x2 = ROTR32(x2, 10); } x->w[0] = x0; x->w[1] = x1; @@ -227,10 +227,10 @@ void serpent_set_encrypt_key(serpent_key_t *key, const unsigned char *user_key) uint32_t i, j; - // copy key input to local buffer + /* copy key input to local buffer */ memcpy(&s_ws.b[0], user_key, SERPENT_KEY256); - // expand the key + /* expand the key */ for (i = 0; i <= SERPENT_ROUNDS; i++) { for (j = 0; j<4; j++) { key->x[i][j] = serpent_gen_w(s_ws.w, i * 4 + j); @@ -241,39 +241,67 @@ void serpent_set_encrypt_key(serpent_key_t *key, const unsigned char *user_key) } } -void serpent_encrypt(void *in, serpent_key_t *key) +void serpent_set_decrypt_key(serpent_key_t *key, const unsigned char *user_key) +{ + union { + uint8_t b[32]; + uint32_t w[8]; + } s_ws; + + uint32_t i, j; + + /* copy key input to local buffer */ + memcpy(&s_ws.b[0], user_key, SERPENT_KEY256); + + /* expand the key */ + for (i = 0; i <= SERPENT_ROUNDS; i++) { + for (j = 0; j<4; j++) { + key->x[i][j] = serpent_gen_w(s_ws.w, i * 4 + j); + memmove(&s_ws.b, &s_ws.b[4], 7 * 4); + s_ws.w[7] = key->x[i][j]; + } + serpent_subbytes((serpent_blk*)&key->x[i], 3 - i, SERPENT_ENCRYPT); + } +} + +void serpent_encrypt(const void *in, void *out, serpent_key_t *key) { int8_t i; - serpent_blk *out = in; + memcpy(out, in, SERPENT_BLOCK_SIZE); + serpent_blk *_out = out; - i = 0; - for (;;) { - // xor with subkey - serpent_whiten(out, key, i); - // apply sbox - serpent_subbytes(out, i, SERPENT_ENCRYPT); - if (++i == SERPENT_ROUNDS) break; - // linear transformation - serpent_lt(out, SERPENT_ENCRYPT); - } - serpent_whiten(out, key, i); + i = 0; + for (;;) { + /* xor with subkey */ + serpent_whiten(_out, key, i); + /* apply sbox */ + serpent_subbytes(_out, i, SERPENT_ENCRYPT); + if (++i == SERPENT_ROUNDS) + break; + /* linear transformation */ + serpent_lt(_out, SERPENT_ENCRYPT); + } + serpent_whiten(_out, key, i); } -void serpent_decrypt(void *in, serpent_key_t *key) +void serpent_decrypt(const void *in, void *out, serpent_key_t *key) { - int8_t i; - serpent_blk *out = in; + int8_t i; + memcpy(out, in, SERPENT_BLOCK_SIZE); - i = SERPENT_ROUNDS; - serpent_whiten(out, key, i); - for (;;) { - --i; - // apply sbox - serpent_subbytes(out, i, SERPENT_DECRYPT); - // xor with subkey - serpent_whiten(out, key, i); - if (i == 0) break; - // linear transformation - serpent_lt(out, SERPENT_DECRYPT); - } + serpent_blk *_out = out; + + i = SERPENT_ROUNDS; + serpent_whiten(_out, key, i); + for (;;) { + --i; + /* apply sbox */ + serpent_subbytes(_out, i, SERPENT_DECRYPT); + /* xor with subkey */ + serpent_whiten(_out, key, i); + if (i == 0) + break; + /* linear transformation */ + serpent_lt(_out, SERPENT_DECRYPT); + } }