diff --git a/src/tf.c b/src/tf.c index 8fc79b0..59fdadc 100644 --- a/src/tf.c +++ b/src/tf.c @@ -465,6 +465,7 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, const unsigned char *iv, tf_context_t *ctx) { uint8_t tmp[TF_BLOCK_SIZE]; + uint8_t old[TF_BLOCK_SIZE]; size_t i; size_t n; @@ -472,9 +473,10 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, n = in_len / TF_BLOCK_SIZE; for(i=0; i < n; i++) { + memcpy(old, &in[i * TF_BLOCK_SIZE], TF_BLOCK_SIZE); twofish_internal_decrypt(ctx->K, ctx->QF, &out[i * TF_BLOCK_SIZE], &in[i * TF_BLOCK_SIZE]); fix_xor(&out[i * TF_BLOCK_SIZE], tmp); - memcpy(tmp, &in[i * TF_BLOCK_SIZE], TF_BLOCK_SIZE); + memcpy(tmp, old, TF_BLOCK_SIZE); } return n * TF_BLOCK_SIZE; diff --git a/src/transform_tf.c b/src/transform_tf.c index 4842c4e..b081fb6 100644 --- a/src/transform_tf.c +++ b/src/transform_tf.c @@ -29,7 +29,7 @@ // cbc mode is being used with random value prepended to plaintext // instead of iv so, actual iv is null_iv -uint8_t null_iv[TF_IV_SIZE] = {0}; +const uint8_t null_iv[TF_IV_SIZE] = {0}; typedef struct transop_tf { tf_context_t *ctx; @@ -70,6 +70,7 @@ static int transop_encode_tf(n2n_trans_op_t * arg, // the assembly buffer is a source for encrypting data // the whole contents of assembly are encrypted uint8_t assembly[N2N_PKT_BUF_SIZE]; + uint8_t assembly2[N2N_PKT_BUF_SIZE]; size_t idx = 0; int padded_len; uint8_t padding; @@ -83,10 +84,10 @@ static int transop_encode_tf(n2n_trans_op_t * arg, // full block sized random value (128 bit) // !!! replace with 2 calls to encode_uint64(...) as as available // !!! which is still under consideration in pull request 'revAes' - encode_uint32(assembly, &idx, 0); - encode_uint32(assembly, &idx, 0); - encode_uint32(assembly, &idx, 0); - encode_uint32(assembly, &idx, 0); + encode_uint32(assembly, &idx, n2n_rand()); + encode_uint32(assembly, &idx, n2n_rand()); + encode_uint32(assembly, &idx, n2n_rand()); + encode_uint32(assembly, &idx, n2n_rand()); // adjust for maybe differently chosen TF_PREAMBLE_SIZE idx = TF_PREAMBLE_SIZE; @@ -100,12 +101,11 @@ static int transop_encode_tf(n2n_trans_op_t * arg, // pad the following bytes with zero, fixed length (TF_BLOCK_SIZE) seems to compile // to slightly faster code than run-time dependant 'padding' memset (assembly + idx, 0, TF_BLOCK_SIZE); - tf_cbc_encrypt(outbuf, assembly, padded_len, null_iv, priv->ctx); if(padding) { // exchange last two cipher blocks - memcpy (buf, outbuf+padded_len - TF_BLOCK_SIZE, TF_BLOCK_SIZE); + memcpy (buf, outbuf + padded_len - TF_BLOCK_SIZE, TF_BLOCK_SIZE); memcpy (outbuf + padded_len - TF_BLOCK_SIZE, outbuf + padded_len - 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE); memcpy (outbuf + padded_len - 2 * TF_BLOCK_SIZE, buf, TF_BLOCK_SIZE); } @@ -156,7 +156,9 @@ static int transop_decode_tf(n2n_trans_op_t * arg, // write new penultimate block from buf memcpy(assembly + penultimate_block, buf, TF_BLOCK_SIZE); // regular cbc decryption on the re-arranged ciphertext + tf_cbc_decrypt(assembly, assembly, in_len + TF_BLOCK_SIZE - rest, null_iv, priv->ctx); + // check for expected zero padding and give a warning otherwise if (memcmp(assembly + in_len, null_iv, TF_BLOCK_SIZE - rest)) { traceEvent(TRACE_WARNING, "transop_decode_tf payload decryption failed with unexpected cipher text stealing padding");