int main(){ char plaintext[] = "Hi I am an AES CBC test vector distributed on 4 128-bit blocks!"; uint8_t key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; uint8_t iv[16] = {0x01, 0xff, 0x83, 0xf2, 0xf9, 0x98, 0xba, 0xa4, 0xda, 0xdc, 0xaa, 0xcc, 0x8e, 0x17, 0xa4, 0x1b}; uint8_t ciphertext[sizeof(plaintext)]; uint8_t deciphertext[sizeof(plaintext)]; struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx; printf("Plaintext: \"%s\"\n", plaintext); printf("IV: "); fprintBuffer_raw(stdout, (char*)iv, sizeof(iv)); printf("\nKey 128: "); fprintBuffer_raw(stdout, (char*)key, sizeof(key)); CBC_SET_IV(&ctx, iv); CBC_SET_ENC_KEY(&ctx, key); CBC_ENCRYPT(&ctx, aes_encrypt, sizeof(plaintext), ciphertext, (uint8_t*)plaintext); CBC_SET_IV(&ctx, iv); CBC_SET_DEC_KEY(&ctx, key); CBC_DECRYPT(&ctx, aes_decrypt, sizeof(ciphertext), deciphertext, ciphertext); printf("\nCiphertext CBC: "); fprintBuffer_raw(stdout, (char*)ciphertext, sizeof(plaintext)); if (memcmp(deciphertext, plaintext, sizeof(plaintext)) == 0){ printf("\nRecovery: OK\n"); } else{ printf("\nRecovery: FAIL\n"); } return EXIT_SUCCESS; }
term_t cbif_aes_cbc_crypt4(proc_t *proc, term_t *regs) { term_t Key = regs[0]; term_t IVec = regs[1]; term_t Data = regs[2]; term_t Dir = regs[3]; if (!is_list(Key) && !is_boxed_binary(Key)) badarg(Key); if (!is_boxed_binary(IVec)) badarg(IVec); if (!is_list(Data) && !is_boxed_binary(Data)) badarg(Data); if (!is_bool(Dir)) badarg(Dir); int key_size = iolist_size(Key); if (key_size < AES_MIN_KEY_SIZE || key_size > AES_MAX_KEY_SIZE) badarg(Key); uint8_t key_buf[key_size]; iolist_flatten(Key, key_buf); bits_t src, dst; bits_get_real(peel_boxed(IVec), &src); if (src.ends -src.starts != AES_BLOCK_SIZE *8) badarg(IVec); uint8_t ivec_buf[AES_BLOCK_SIZE]; bits_init_buf(ivec_buf, AES_BLOCK_SIZE, &dst); bits_copy(&src, &dst); int data_size = iolist_size(Data); if (data_size < 0) badarg(Data); assert(data_size <= 65536); //TODO: use heap_tmp_buf for larger Data uint8_t data_buf[data_size]; iolist_flatten(Data, data_buf); struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx; if (Dir == A_TRUE) aes_set_encrypt_key((struct aes_ctx *)&ctx, key_size, key_buf); else aes_set_decrypt_key((struct aes_ctx *)&ctx, key_size, key_buf); CBC_SET_IV(&ctx, ivec_buf); uint8_t *ptr; term_t cipher_text = heap_make_bin(&proc->hp, data_size, &ptr); if (Dir == A_TRUE) CBC_ENCRYPT(&ctx, aes_encrypt, data_size, ptr, data_buf); else CBC_DECRYPT(&ctx, aes_decrypt, data_size, ptr, data_buf); return cipher_text; }
static void test_cbc_bulk(void) { struct knuth_lfib_ctx random; uint8_t clear[CBC_BULK_DATA]; uint8_t cipher[CBC_BULK_DATA + 1]; const uint8_t *key = H("966c7bf00bebe6dc 8abd37912384958a" "743008105a08657d dcaad4128eee38b3"); const uint8_t *start_iv = H("11adbff119749103 207619cfa0e8d13a"); const uint8_t *end_iv = H("c7a42a569b421224 d0c23e52f46f97f5"); struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes; knuth_lfib_init(&random, CBC_BULK_DATA); knuth_lfib_random(&random, CBC_BULK_DATA, clear); /* Byte that should not be overwritten */ cipher[CBC_BULK_DATA] = 17; aes_set_encrypt_key(&aes.ctx, 32, key); CBC_SET_IV(&aes, start_iv); CBC_ENCRYPT(&aes, aes_encrypt, CBC_BULK_DATA, cipher, clear); ASSERT(cipher[CBC_BULK_DATA] == 17); if (verbose) { printf("IV after bulk encryption: "); print_hex(AES_BLOCK_SIZE, aes.iv); printf("\n"); } ASSERT(MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv)); /* Decrypt, in place */ aes_set_decrypt_key(&aes.ctx, 32, key); CBC_SET_IV(&aes, start_iv); CBC_DECRYPT(&aes, aes_decrypt, CBC_BULK_DATA, cipher, cipher); ASSERT(cipher[CBC_BULK_DATA] == 17); if (verbose) { printf("IV after bulk decryption: "); print_hex(AES_BLOCK_SIZE, aes.iv); printf("\n"); } ASSERT (MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv)); ASSERT (MEMEQ(CBC_BULK_DATA, clear, cipher)); }
static gboolean decrypt_fragment (GstHLSDemux * demux, gsize length, const guint8 * encrypted_data, guint8 * decrypted_data) { if (length % 16 != 0) return FALSE; CBC_DECRYPT (&demux->aes_ctx, aes_decrypt, length, decrypted_data, encrypted_data); return TRUE; }
static int process_file(struct rsa_session *ctx, FILE *in, FILE *out) { uint8_t buffer[BUF_SIZE + BUF_FINAL]; uint8_t digest[SHA1_DIGEST_SIZE]; size_t size; unsigned padding; size = fread(buffer, 1, BUF_FINAL, in); if (size < BUF_FINAL) { if (ferror(in)) werror("Reading input failed: %s\n", strerror(errno)); else werror("Unexpected EOF on input.\n"); return 0; } do { size = fread(buffer + BUF_FINAL, 1, BUF_SIZE, in); if (size < BUF_SIZE && ferror(in)) { werror("Reading input failed: %s\n", strerror(errno)); return 0; } if (size % AES_BLOCK_SIZE != 0) { werror("Unexpected EOF on input.\n"); return 0; } if (size) { CBC_DECRYPT(&ctx->aes, aes256_decrypt, size, buffer, buffer); hmac_sha1_update(&ctx->hmac, size, buffer); if (!write_data(out, size, buffer)) { werror("Writing output failed: %s\n", strerror(errno)); return 0; } memmove(buffer, buffer + size, BUF_FINAL); } } while (size == BUF_SIZE); /* Decrypt final block */ CBC_DECRYPT(&ctx->aes, aes256_decrypt, AES_BLOCK_SIZE, buffer, buffer); padding = buffer[AES_BLOCK_SIZE - 1]; if (padding > AES_BLOCK_SIZE) { werror("Decryption failed: Invalid padding.\n"); return 0; } if (padding < AES_BLOCK_SIZE) { unsigned leftover = AES_BLOCK_SIZE - padding; hmac_sha1_update(&ctx->hmac, leftover, buffer); if (!write_data(out, leftover, buffer)) { werror("Writing output failed: %s\n", strerror(errno)); return 0; } } hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, digest); if (!memeql_sec(digest, buffer + AES_BLOCK_SIZE, SHA1_DIGEST_SIZE)) { werror("Decryption failed: Invalid mac.\n"); return 0; } return 1; }