void tmd_aes_generic_encrypt_ctr(uint8_t *output, const aes_key *key, const aes_block *iv, aes_block *newIV, const uint8_t *input, uint32_t len) { aes_block block, o; uint32_t nb_blocks = len / 16; int i; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; block128_inc_be(&block), output += 16, input += 16) { aes_encrypt_block(&o, key, &block); block128_vxor((block128 *) output, &o, (block128 *) input); } if ((len % 16) != 0) { aes_encrypt_block(&o, key, &block); for (i = 0; i < (len % 16); i++) { *output = ((uint8_t *) &o)[i] ^ *input; output++; input++; } } if(NULL != newIV) block128_copy(newIV, &block); }
void aes_decrypt_cbc(uint8_t *output, aes_key *key, aes_block *ivini, uint8_t *input, uint32_t nb_blocks) { aes_block block,blocko; aes_block iv; if (!nb_blocks) return; #if defined(ARCH_X86) && defined(WITH_AESNI) if (have_aesni() && key->nbr == 10) { return aes_ni_decrypt_cbc(output, key, (uint8_t *) ivini, input, nb_blocks); } #endif /* preload IV in block */ block128_copy(&iv, ivini); aes_decrypt_block(&block, key, &block); for ( ;nb_blocks-- > 0; input += 16, output += 16) { block128_copy(&block, (block128 *) input); aes_decrypt_block(&blocko, key, &block); block128_vxor((block128 *) output, &blocko, &iv); block128_copy(&iv, &block); } }
void tmd_aes_generic_encrypt_cbc(aes_block *output, const aes_key *key, const aes_block *iv, aes_block *newIV, const aes_block *input, uint32_t nb_blocks) { /* preload IV in block */ block128_copy(newIV, iv); for ( ; nb_blocks-- > 0; input++, output++) { block128_xor(newIV, (block128 *) input); tmd_aes_generic_encrypt_block(newIV, key, newIV); block128_copy((block128 *) output, newIV); } }
void tmd_aes_generic_decrypt_cbc(aes_block *output, const aes_key *key, const aes_block *ivini, aes_block *newIV, const aes_block *input, uint32_t nb_blocks) { aes_block block, blocko; aes_block *iv; iv = newIV; /* preload IV in block */ block128_copy(iv, ivini); for ( ; nb_blocks-- > 0; input++, output++) { block128_copy(&block, (block128 *) input); tmd_aes_generic_decrypt_block(&blocko, key, &block); block128_vxor((block128 *) output, &blocko, iv); block128_copy(iv, &block); } }
void tmd_aes_generic_gcm_decrypt(uint8_t *output, const aes_gcm *gcm, const aes_ctx *ctx, const aes_key *key, const uint8_t *input, uint32_t length, aes_ctx *newCTX) { aes_block out; memcpy(newCTX, ctx, sizeof(aes_ctx)); newCTX->length_input += length; for (; length >= 16; input += 16, output += 16, length -= 16) { block128_inc_be(&newCTX->civ); aes_encrypt_block(&out, key, &newCTX->civ); gcm_ghash_add(gcm, newCTX, (block128 *) input); block128_xor(&out, (block128 *) input); block128_copy((block128 *) output, &out); } if (length > 0) { aes_block tmp; int i; block128_inc_be(&newCTX->civ); block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); gcm_ghash_add(gcm, newCTX, &tmp); aes_encrypt_block(&out, key, &newCTX->civ); block128_xor_bytes(&tmp, out.b, length); for (i = 0; i < length; i++) { output[i] = tmp.b[i]; } } }
void tmd_aes_ctx_init(const aes_gcm *gcm, aes_ctx *ctx , const aes_key *key, const uint8_t *iv, uint32_t len) { ctx->length_aad = 0; ctx->length_input = 0; block128_zero(&ctx->tag); block128_zero(&ctx->iv); if (len == 12) { block128_copy_bytes(&ctx->iv, iv, 12); ctx->iv.b[15] = 0x01; } else { uint32_t origlen = len << 3; int i; for (; len >= 16; len -= 16, iv += 16) { block128_xor(&ctx->iv, (block128 *) iv); tmd_gf_mul(&ctx->iv, &gcm->h); } if (len > 0) { block128_xor_bytes(&ctx->iv, iv, len); tmd_gf_mul(&ctx->iv, &gcm->h); } for (i = 15; origlen; --i, origlen >>= 8) ctx->iv.b[i] ^= (uint8_t) origlen; tmd_gf_mul(&ctx->iv, &gcm->h); } block128_copy(&ctx->civ, &ctx->iv); }
void aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, uint8_t *input, uint32_t length) { aes_block out; gcm->length_input += length; for (; length >= 16; input += 16, output += 16, length -= 16) { block128_inc_be(&gcm->civ); aes_encrypt_block(&out, &gcm->key, &gcm->civ); gcm_ghash_add(gcm, (block128 *) input); block128_xor(&out, (block128 *) input); block128_copy((block128 *) output, &out); } if (length > 0) { aes_block tmp; int i; block128_inc_be(&gcm->civ); block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); gcm_ghash_add(gcm, &tmp); aes_encrypt_block(&out, &gcm->key, &gcm->civ); block128_xor_bytes(&tmp, out.b, length); for (i = 0; i < length; i++) { output[i] = tmp.b[i]; } } }
void aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len) { gcm->length_aad = 0; gcm->length_input = 0; block128_zero(&gcm->h); block128_zero(&gcm->tag); block128_zero(&gcm->iv); memcpy(&gcm->key, key, sizeof(aes_key)); /* prepare H : encrypt_K(0^128) */ aes_encrypt_block(&gcm->h, key, &gcm->h); if (len == 12) { block128_copy_bytes(&gcm->iv, iv, 12); gcm->iv.b[15] = 0x01; } else { uint32_t origlen = len << 3; int i; for (; len >= 16; len -= 16, iv += 16) { block128_xor(&gcm->iv, (block128 *) iv); gf_mul(&gcm->iv, &gcm->h); } if (len > 0) { block128_xor_bytes(&gcm->iv, iv, len); gf_mul(&gcm->iv, &gcm->h); } for (i = 15; origlen; --i, origlen >>= 8) gcm->iv.b[i] ^= (uint8_t) origlen; gf_mul(&gcm->iv, &gcm->h); } block128_copy(&gcm->civ, &gcm->iv); }
void aes_encrypt_xts(uint8_t *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, uint8_t *input, uint32_t nb_blocks) { aes_block block, tweak; if (!nb_blocks) return; #if defined(ARCH_X86) && defined(WITH_AESNI) if (have_aesni() && k1->nbr == 10) { aes_ni_encrypt_xts(output, k1, k2, (uint8_t *) dataunit, spoint, input, nb_blocks); return; } #endif /* load IV and encrypt it using k2 as the tweak */ block128_copy(&tweak, dataunit); aes_encrypt_block(&tweak, k2, &tweak); /* TO OPTIMISE: this is really inefficient way to do that */ while (spoint-- > 0) gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input += 16, output += 16, gf_mulx(&tweak)) { block128_vxor(&block, (block128 *) input, &tweak); aes_encrypt_block(&block, k1, &block); block128_vxor((block128 *) output, &block, &tweak); } }
void tmd_aes_gen_ctr(aes_block *output, const aes_key *key, aes_block *iv, uint32_t nb_blocks) { aes_block block; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; output++, block128_inc_be(&block)) { aes_encrypt_block(output, key, &block); } }
void aes_gen_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint32_t nb_blocks) { aes_block block; if (!nb_blocks) return; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; output += 16, block128_inc_be(&block)) { aes_encrypt_block((block128 *) output, key, &block); } }
void tmd_aes_generic_decrypt_xts(aes_block *output, const aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks) { aes_block block, tweak; /* load IV and encrypt it using k2 as the tweak */ block128_copy(&tweak, dataunit); aes_encrypt_block(&tweak, k2, &tweak); /* TO OPTIMISE: this is really inefficient way to do that */ while (spoint-- > 0) tmd_gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input++, output++, tmd_gf_mulx(&tweak)) { block128_vxor(&block, input, &tweak); aes_decrypt_block(&block, k1, &block); block128_vxor(output, &block, &tweak); } }
void aes_decrypt_xts(uint8_t *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, uint8_t *input, uint32_t nb_blocks) { aes_block block, tweak; if (!nb_blocks) return; /* load IV and encrypt it using k2 as the tweak */ block128_copy(&tweak, dataunit); aes_encrypt_block(&tweak, k2, &tweak); /* TO OPTIMISE: this is really inefficient way to do that */ while (spoint-- > 0) gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input += 16, output += 16, gf_mulx(&tweak)) { block128_vxor(&block, (block128 *) input, &tweak); aes_decrypt_block(&block, k1, &block); block128_vxor((block128 *) output, &block, &tweak); } }
void aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len) { aes_block block, o; uint32_t nb_blocks = len / 16; int i; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; block128_inc_be(&block), output += 16, input += 16) { aes_encrypt_block(&o, key, &block); block128_vxor((block128 *) output, &o, (block128 *) input); } if ((len % 16) != 0) { aes_encrypt_block(&o, key, &block); for (i = 0; i < (len % 16); i++) { *output = ((uint8_t *) &o)[i] ^ *input; output += 1; input += 1; } } }