static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher, const void *in, void *out, size_t len, Error **errp) { QCryptoCipherBuiltin *ctxt = cipher->opaque; switch (cipher->mode) { case QCRYPTO_CIPHER_MODE_ECB: qcrypto_cipher_aes_ecb_decrypt(&ctxt->state.aes.key.dec, in, out, len); break; case QCRYPTO_CIPHER_MODE_CBC: AES_cbc_encrypt(in, out, len, &ctxt->state.aes.key.dec, ctxt->state.aes.iv, 0); break; case QCRYPTO_CIPHER_MODE_XTS: xts_decrypt(&ctxt->state.aes.key, &ctxt->state.aes.key_tweak, qcrypto_cipher_aes_xts_encrypt, qcrypto_cipher_aes_xts_decrypt, ctxt->state.aes.iv, len, out, in); break; default: g_assert_not_reached(); } return 0; }
static int _xts_test_accel_xts_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, symmetric_key *skey2) { int ret; symmetric_xts xts; int (*orig)(const unsigned char *, unsigned char *, unsigned long , unsigned char *, symmetric_key *, symmetric_key *); /* AES can be under rijndael or aes... try to find it */ if ((xts.cipher = find_cipher("aes")) == -1) { if ((xts.cipher = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } orig = cipher_descriptor[xts.cipher].accel_xts_decrypt; cipher_descriptor[xts.cipher].accel_xts_decrypt = NULL; XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key)); XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key)); ret = xts_decrypt(ct, blocks << 4, pt, tweak, &xts); cipher_descriptor[xts.cipher].accel_xts_decrypt = orig; return ret; }
void dc_fast_crypt_op( int is_encrypt, xts_key *key, const unsigned char *in, unsigned char *out, u32 len, u64 offset) { KEVENT sync_event; int succs; if ( (len >= F_OP_THRESOLD) && (dc_cpu_count > 1) ) { KeInitializeEvent(&sync_event, NotificationEvent, FALSE); succs = dc_parallelized_crypt( is_encrypt, key, dc_fast_op_complete, &sync_event, NULL, in, out, len, offset); if (succs != 0) { KeWaitForSingleObject(&sync_event, Executive, KernelMode, FALSE, NULL); return; } } if (is_encrypt != 0) { xts_encrypt(in, out, len, offset, key); } else { xts_decrypt(in, out, len, offset, key); } }
int try_decrypt(char *passphrase) { struct xts_ctx *xts_ctx; struct pbkdf_prf *prf; int dklen = 64; uint8_t *dk; uint32_t sector = 0; uint32_t crc; int ret = -1; dk = malloc(dklen); xts_ctx = malloc(sizeof(struct xts_ctx)); for (prf = &prfs[0]; prf->hmac_fn != NULL; ++prf) { /* We decrypt in place, so we have to re-read every time */ bios_read_sectors(biosdev, &hdr, 63, 1); pbkdf2(dk, dklen, passphrase, strlen(passphrase), hdr.enc.salt, SALT_LEN, prf->iterations, prf->hmac_fn, prf->digest_sz); #ifdef DEBUG bios_print_hex(dk, dklen); bios_print("\r\n"); #endif xts_init(xts_ctx, aes256_init, aes256_encrypt_ecb, aes256_decrypt_ecb, 16, dk, dklen); xts_decrypt(xts_ctx, hdr.enc.enc, sizeof(hdr.enc.enc), §or, sizeof(sector)); xts_uninit(xts_ctx); if (memcmp(hdr.dec.tc_str, TC_SIG, sizeof(hdr.dec.tc_str)) != 0) { bios_print("Signature mismatch\r\n"); continue; } bswap_inplace(&hdr.dec.tc_ver, sizeof(hdr.dec.tc_ver)); bswap_inplace(&hdr.dec.crc_keys, sizeof(hdr.dec.crc_keys)); bswap_inplace(&hdr.dec.off_mk_scope, sizeof(hdr.dec.off_mk_scope)); bswap_inplace(&hdr.dec.sz_mk_scope, sizeof(hdr.dec.sz_mk_scope)); bswap_inplace(&hdr.dec.flags, sizeof(hdr.dec.flags)); crc = crc32((void *)hdr.dec.keys, sizeof(hdr.dec.keys)); if (crc != hdr.dec.crc_keys) { bios_print("Keys CRC mismatch\r\n"); continue; } ret = 0; break; } free (dk, dklen); free (xts_ctx, sizeof(struct xts_ctx)); return ret; }
static void dc_simple_encryption_test() { PXTS_TEST_CONTEXT ctx; unsigned char dk[256]; unsigned long e_crc, d_crc, i; // test PKDBF2 for (i = 0; i < (sizeof(pkcs5_vectors) / sizeof(pkcs5_vectors[0])); i++) { sha512_pkcs5_2(pkcs5_vectors[i].i_count, pkcs5_vectors[i].password, strlen(pkcs5_vectors[i].password), pkcs5_vectors[i].salt, strlen(pkcs5_vectors[i].salt), dk, pkcs5_vectors[i].dklen); if (memcmp(dk, pkcs5_vectors[i].key, pkcs5_vectors[i].dklen) != 0) { KeBugCheckEx(STATUS_ENCRYPTION_FAILED, 'DCRP', i, 0, 0); } } DbgMsg("PKDBF2 test passed\n"); // test XTS engine if memory may be allocated if ( (KeGetCurrentIrql() <= DISPATCH_LEVEL) && (ctx = (PXTS_TEST_CONTEXT)mm_secure_alloc(sizeof(XTS_TEST_CONTEXT))) != NULL ) { // fill key and test buffer for (i = 0; i < (sizeof(ctx->key) / sizeof(ctx->key[0])); i++) ctx->key[i] = (unsigned char)i; for (i = 0; i < (sizeof(ctx->test) / sizeof(ctx->test[0])); i++) ctx->test[i] = (unsigned short)i; // run test cases for (i = 0; i < (sizeof(xts_crc_vectors) / sizeof(xts_crc_vectors[0])); i++) { xts_set_key(ctx->key, xts_crc_vectors[i].alg, &ctx->xkey); xts_encrypt((const unsigned char*)ctx->test, (unsigned char*)ctx->buff, sizeof(ctx->test), 0x3FFFFFFFC00, &ctx->xkey); e_crc = crc32((const unsigned char*)ctx->buff, sizeof(ctx->buff)); xts_decrypt((const unsigned char*)ctx->test, (unsigned char*)ctx->buff, sizeof(ctx->test), 0x3FFFFFFFC00, &ctx->xkey); d_crc = crc32((const unsigned char*)ctx->buff, sizeof(ctx->buff)); if ( e_crc != xts_crc_vectors[i].e_crc || d_crc != xts_crc_vectors[i].d_crc ) { KeBugCheckEx(STATUS_ENCRYPTION_FAILED, 'DCRP', 0xFF00 | i, e_crc, d_crc); } } DbgMsg("XTS test passed\n"); mm_secure_free(ctx); } }
void cp_parallelized_crypt( int is_encrypt, xts_key *key, fc_callback on_complete, void *param, const unsigned char *in, unsigned char *out, u32 len, u64 offset) { req_item *item; req_part *part; u32 part_sz; u32 part_of; if ( (len < F_OP_THRESOLD) || ((item = ExAllocateFromNPagedLookasideList(&pool_req_mem)) == NULL) ) { if (is_encrypt != 0) { xts_encrypt(in, out, len, offset, key); } else { xts_decrypt(in, out, len, offset, key); } on_complete(param); return; } item->is_encrypt = is_encrypt; item->length = len; item->in = in; item->out = out; item->offset = offset; item->on_complete = on_complete; item->param = param; item->key = key; part_sz = _align(len / dc_cpu_count, F_MIN_REQ); part_of = 0; part = &item->parts[0]; do { part_sz = min(part_sz, len); part->item = item; part->offset = part_of; part->length = part_sz; InterlockedPushEntrySList(&pool_head, &part->entry); part_of += part_sz; len -= part_sz; part++; } while (len != 0); KeSetEvent(&pool_signal_event, IO_NO_INCREMENT, FALSE); }
static void dc_worker_thread(void *param) { SLIST_ENTRY *entry; req_part *part; req_item *item; const char *in; char *out; u64 offset; u32 length; do { KeWaitForSingleObject(&pool_signal_event, Executive, KernelMode, FALSE, NULL); KeClearEvent(&pool_signal_event); while (entry = ExInterlockedPopEntrySList(&pool_head, &pool_lock)) { part = CONTAINING_RECORD(entry, req_part, entry); item = part->item; in = item->in + part->offset; out = item->out + part->offset; offset = item->offset + part->offset; length = part->length; if (item->is_encrypt != 0) { xts_encrypt(in, out, length, offset, item->key); } else { xts_decrypt(in, out, length, offset, item->key); } if (lock_xchg_add(&item->length, 0-length) == length) { item->on_complete(item->param1, item->param2); ExFreeToNPagedLookasideList(&pool_req_mem, item); } } } while (pool_enabled != 0); PsTerminateSystemThread(STATUS_SUCCESS); }
int cp_decrypt_header(xts_key *hdr_key, dc_header *header, dc_pass *password) { u8 dk[DISKKEY_SIZE]; int i, succs = 0; dc_header *hcopy; if ( (hcopy = mm_alloc(sizeof(dc_header), MEM_SECURE)) == NULL ) { return 0; } sha512_pkcs5_2( 1000, password->pass, password->size, header->salt, PKCS5_SALT_SIZE, dk, PKCS_DERIVE_MAX); for (i = 0; i < CF_CIPHERS_NUM; i++) { xts_set_key(dk, i, hdr_key); xts_decrypt( pv(header), pv(hcopy), sizeof(dc_header), 0, hdr_key); /* Magic 'DCRP' */ if (hcopy->sign != DC_VOLM_SIGN) { continue; } /* Check CRC of header */ if (hcopy->hdr_crc != crc32(pv(&hcopy->version), DC_CRC_AREA_SIZE)) { continue; } /* copy decrypted part to output */ memcpy(&header->sign, &hcopy->sign, DC_ENCRYPTEDDATASIZE); succs = 1; break; } /* prevent leaks */ burn(dk, sizeof(dk)); mm_free(hcopy); return succs; }
// ========================================================================= // Decryption function // Note: PlaintextLength must be set to the size of the PlaintextData buffer on // entry; on exit, this will be set to the size of the buffer used. NTSTATUS ImpCypherDecryptSectorData( IN GUID* CypherGUID, IN LARGE_INTEGER SectorID, // Indexed from zero IN int SectorSize, // In bytes IN int KeyLength, // In bits IN FREEOTFEBYTE* Key, IN char* KeyASCII, // ASCII representation of "Key" IN int IVLength, // In bits IN FREEOTFEBYTE* IV, IN int CyphertextLength, // In bytes IN FREEOTFEBYTE* CyphertextData, OUT FREEOTFEBYTE* PlaintextData ) { NTSTATUS status = STATUS_SUCCESS; // Null IV in case we're not given an IV char zeroIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE]; int i; INTEGER_128 blockID128; int errnum; TWOFISH(CONTEXT) context; DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDecryptData\n"))); if ( (IsEqualGUID(&CIPHER_GUID_TWOFISH_256_XTS, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_TWOFISH_192_XTS, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_TWOFISH_128_XTS, CypherGUID)) ) { // Generate index in correct format // XTS uses: // *) The sector index (i.e. the number of N-bit sectors) // *) The first sector is sector 0 // *) Littleendian format LARGE_INTEGER__To__INTEGER_128_LittleEndian( SectorID, blockID128 ); if ((errnum = xts_decrypt( &context, &(TWOFISH(set_key)), &(TWOFISH(encrypt)), &(TWOFISH(decrypt)), ((KeyLength/2)), Key, ((KeyLength/2)), &(Key[(KeyLength/2)/8]), CyphertextData, CyphertextLength, PlaintextData, blockID128 )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to decrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } else if ( (IsEqualGUID(&CIPHER_GUID_TWOFISH_256_CBC, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_TWOFISH_192_CBC, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_TWOFISH_128_CBC, CypherGUID)) ) { // Handle situation where a NULL/zero length IV is passed in if ( (IVLength == 0) || (IV == NULL) ) { FREEOTFE_MEMZERO(&zeroIV, sizeof(zeroIV)); IV = (char*)&zeroIV; } // Process data using CBC mode // // CBC Mode DECRYPT: // *) Setup key // *) For each block... // *) Decrypt cyphertext with key // *) XOR output plaintext with IV // *) IV = Cyphertext data // Note: "dec" specified; we're DECRYPTING TWOFISH(set_key)(&context, Key, KeyLength, dec); for (i=0; i < CyphertextLength; i += (TWOFISH_BLOCK_SIZE / 8)) { TWOFISH(decrypt)(&context, CyphertextData+i, PlaintextData+i); XORBlock(PlaintextData+i, IV, PlaintextData+i, (TWOFISH_BLOCK_SIZE / 8)); IV = CyphertextData+i; } } else { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unsupported cipher GUID passed in.\n"))); status = STATUS_INVALID_PARAMETER; } SecZeroMemory(&context, sizeof(context)); DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDecryptData\n"))); return status; }
/** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects Returns CRYPT_OK upon success. */ int xts_test(void) { #ifdef LTC_NO_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key1[32]; unsigned char key2[32]; ulong64 seqnum; unsigned long PTLEN; unsigned char PTX[512], CTX[512]; } tests[] = { /* #1 32 byte key, 32 byte PTX */ { 32, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 32, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x91,0x7c,0xf6,0x9e,0xbd,0x68,0xb2,0xec,0x9b,0x9f,0xe9,0xa3,0xea,0xdd,0xa6,0x92,0xcd,0x43,0xd2,0xf5,0x95,0x98,0xed,0x85,0x8c,0x02,0xc2,0x65,0x2f,0xbf,0x92,0x2e }, }, /* #2, 32 byte key, 32 byte PTX */ { 32, { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11 }, { 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 }, CONST64(0x3333333333), 32, { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, { 0xc4,0x54,0x18,0x5e,0x6a,0x16,0x93,0x6e,0x39,0x33,0x40,0x38,0xac,0xef,0x83,0x8b,0xfb,0x18,0x6f,0xff,0x74,0x80,0xad,0xc4,0x28,0x93,0x82,0xec,0xd6,0xd3,0x94,0xf0 }, }, /* #5 from xts.7, 32 byte key, 32 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 32, { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, { 0xb0,0x1f,0x86,0xf8,0xed,0xc1,0x86,0x37,0x06,0xfa,0x8a,0x42,0x53,0xe3,0x4f,0x28,0xaf,0x31,0x9d,0xe3,0x83,0x34,0x87,0x0f,0x4d,0xd1,0xf9,0x4c,0xbe,0x98,0x32,0xf1 }, }, /* #4, 32 byte key, 512 byte PTX */ { 32, { 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26 }, { 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95 }, 0, 512, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, }, { 0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c, 0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12, 0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce, 0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65, 0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,0xa1,0x0c,0x42,0x11,0x10,0xe6,0xd8,0x15,0x88,0xed,0xe8,0x21,0x03,0xa2,0x52,0xd8, 0xa7,0x50,0xe8,0x76,0x8d,0xef,0xff,0xed,0x91,0x22,0x81,0x0a,0xae,0xb9,0x9f,0x91,0x72,0xaf,0x82,0xb6,0x04,0xdc,0x4b,0x8e,0x51,0xbc,0xb0,0x82,0x35,0xa6,0xf4,0x34, 0x13,0x32,0xe4,0xca,0x60,0x48,0x2a,0x4b,0xa1,0xa0,0x3b,0x3e,0x65,0x00,0x8f,0xc5,0xda,0x76,0xb7,0x0b,0xf1,0x69,0x0d,0xb4,0xea,0xe2,0x9c,0x5f,0x1b,0xad,0xd0,0x3c, 0x5c,0xcf,0x2a,0x55,0xd7,0x05,0xdd,0xcd,0x86,0xd4,0x49,0x51,0x1c,0xeb,0x7e,0xc3,0x0b,0xf1,0x2b,0x1f,0xa3,0x5b,0x91,0x3f,0x9f,0x74,0x7a,0x8a,0xfd,0x1b,0x13,0x0e, 0x94,0xbf,0xf9,0x4e,0xff,0xd0,0x1a,0x91,0x73,0x5c,0xa1,0x72,0x6a,0xcd,0x0b,0x19,0x7c,0x4e,0x5b,0x03,0x39,0x36,0x97,0xe1,0x26,0x82,0x6f,0xb6,0xbb,0xde,0x8e,0xcc, 0x1e,0x08,0x29,0x85,0x16,0xe2,0xc9,0xed,0x03,0xff,0x3c,0x1b,0x78,0x60,0xf6,0xde,0x76,0xd4,0xce,0xcd,0x94,0xc8,0x11,0x98,0x55,0xef,0x52,0x97,0xca,0x67,0xe9,0xf3, 0xe7,0xff,0x72,0xb1,0xe9,0x97,0x85,0xca,0x0a,0x7e,0x77,0x20,0xc5,0xb3,0x6d,0xc6,0xd7,0x2c,0xac,0x95,0x74,0xc8,0xcb,0xbc,0x2f,0x80,0x1e,0x23,0xe5,0x6f,0xd3,0x44, 0xb0,0x7f,0x22,0x15,0x4b,0xeb,0xa0,0xf0,0x8c,0xe8,0x89,0x1e,0x64,0x3e,0xd9,0x95,0xc9,0x4d,0x9a,0x69,0xc9,0xf1,0xb5,0xf4,0x99,0x02,0x7a,0x78,0x57,0x2a,0xee,0xbd, 0x74,0xd2,0x0c,0xc3,0x98,0x81,0xc2,0x13,0xee,0x77,0x0b,0x10,0x10,0xe4,0xbe,0xa7,0x18,0x84,0x69,0x77,0xae,0x11,0x9f,0x7a,0x02,0x3a,0xb5,0x8c,0xca,0x0a,0xd7,0x52, 0xaf,0xe6,0x56,0xbb,0x3c,0x17,0x25,0x6a,0x9f,0x6e,0x9b,0xf1,0x9f,0xdd,0x5a,0x38,0xfc,0x82,0xbb,0xe8,0x72,0xc5,0x53,0x9e,0xdb,0x60,0x9e,0xf4,0xf7,0x9c,0x20,0x3e, 0xbb,0x14,0x0f,0x2e,0x58,0x3c,0xb2,0xad,0x15,0xb4,0xaa,0x5b,0x65,0x50,0x16,0xa8,0x44,0x92,0x77,0xdb,0xd4,0x77,0xef,0x2c,0x8d,0x6c,0x01,0x7d,0xb7,0x38,0xb1,0x8d, 0xeb,0x4a,0x42,0x7d,0x19,0x23,0xce,0x3f,0xf2,0x62,0x73,0x57,0x79,0xa4,0x18,0xf2,0x0a,0x28,0x2d,0xf9,0x20,0x14,0x7b,0xea,0xbe,0x42,0x1e,0xe5,0x31,0x9d,0x05,0x68, } }, /* #7, 32 byte key, 17 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 17, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10 }, { 0x6c,0x16,0x25,0xdb,0x46,0x71,0x52,0x2d,0x3d,0x75,0x99,0x60,0x1d,0xe7,0xca,0x09,0xed }, }, /* #15, 32 byte key, 25 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 25, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18 }, { 0x8f,0x4d,0xcb,0xad,0x55,0x55,0x8d,0x7b,0x4e,0x01,0xd9,0x37,0x9c,0xd4,0xea,0x22,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73 }, }, /* #21, 32 byte key, 31 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 31, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e }, { 0xd0,0x5b,0xc0,0x90,0xa8,0xe0,0x4f,0x1b,0x3d,0x3e,0xcd,0xd5,0xba,0xec,0x0f,0xd4,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73,0x06,0xe6,0x4b,0xe5,0xdd,0x82 }, }, }; unsigned char OUT[512], T[16]; ulong64 seq; symmetric_xts xts; int i, err, idx; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen/2, 0, &xts); if (err != CRYPT_OK) { return err; } seq = tests[i].seqnum; STORE64L(seq,T); XMEMSET(T+8, 0, 8); err = xts_encrypt(tests[i].PTX, tests[i].PTLEN, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } if (XMEMCMP(OUT, tests[i].CTX, tests[i].PTLEN)) { xts_done(&xts); return CRYPT_FAIL_TESTVECTOR; } err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) { xts_done(&xts); return CRYPT_FAIL_TESTVECTOR; } xts_done(&xts); } return CRYPT_OK; #endif }
// ========================================================================= // Encrypt/Decrypt function // Note: PlaintextLength must be set to the size of the PlaintextData buffer on // entry; on exit, this will be set to the size of the buffer used. NTSTATUS ImpCypherCryptData( IN GUID* CypherGUID, IN LARGE_INTEGER SectorID, IN int SectorSize, // In bytes IN int KeyLength, // In bits IN FREEOTFEBYTE* Key, IN char* KeyASCII, // ASCII representation of "Key" IN int IVLength, // In bits IN FREEOTFEBYTE* IV, IN BOOLEAN encryptNotDecrypt, // TRUE = encrypt; FALSE = decrypt IN int InLength, // In bytes IN FREEOTFEBYTE* InData, OUT FREEOTFEBYTE* OutData ) { NTSTATUS status = STATUS_SUCCESS; // libtomcrypt can't handle NULL IVs in CBC mode - it ASSERTs that IV != NULL char ltcNullIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE]; int cipher; symmetric_CBC *cbc; symmetric_LRW *lrw; symmetric_xts *xts; int errnum; CYPHER_MODE mode; int keySizeUnderlying; LARGE_INTEGER blockID64; INTEGER_128 blockID128; DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDecryptData\n"))); status = DetermineCypherDetails( CypherGUID, &keySizeUnderlying, &mode ); // libtomcrypt can't handle NULL IVs in CBC mode - it ASSERTs that IV != NULL if ( (IVLength == 0) || (IV == NULL) ) { FREEOTFE_MEMZERO(<cNullIV, sizeof(ltcNullIV)); IV = (char*)<cNullIV; } // Sanity check on key supplied if NT_SUCCESS(status) { switch (mode) { case CYPHER_MODE_CBC: { if (KeyLength != keySizeUnderlying) { status = STATUS_INVALID_PARAMETER; } break; } case CYPHER_MODE_XTS: { if (KeyLength != (2 * keySizeUnderlying)) { status = STATUS_INVALID_PARAMETER; } break; } case CYPHER_MODE_LRW: { if (KeyLength != (keySizeUnderlying + (twofish_desc.block_length * 8))) { status = STATUS_INVALID_PARAMETER; } break; } } } if NT_SUCCESS(status) { status = InitLTCCypher(&cipher); } if NT_SUCCESS(status) { switch (mode) { case CYPHER_MODE_CBC: { cbc = FREEOTFE_MEMALLOC(sizeof(symmetric_CBC)); FREEOTFE_MEMZERO(cbc, sizeof(symmetric_CBC)); // Start a CBC session if ((errnum = cbc_start( cipher, IV, Key, (keySizeUnderlying/8), 0, cbc )) != CRYPT_OK) { status = STATUS_UNSUCCESSFUL; DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to start CBC session (errnum: %d)\n"), errnum)); } else { if (encryptNotDecrypt) { if ((errnum = cbc_encrypt( InData, OutData, InLength, cbc )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to encrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } else { if ((errnum = cbc_decrypt( InData, OutData, InLength, cbc )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to decrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } cbc_done(cbc); } SecZeroMemory(cbc, sizeof(symmetric_CBC)); FREEOTFE_FREE(cbc); break; } case CYPHER_MODE_LRW: { lrw = FREEOTFE_MEMALLOC(sizeof(symmetric_LRW)); FREEOTFE_MEMZERO(lrw, sizeof(symmetric_LRW)); // Generate index in correct format // LRW uses: // *) The block index (i.e. the number of 128 bit blocks) // *) The first block has block index 1 - not 0! // *) Bigendian format // Note: LTC increments this itself as it processes each block SectorIDToBlockIdx_64Bit(SectorID, SectorSize, &blockID64); LARGE_INTEGER__To__INTEGER_128_BigEndian( blockID64, blockID128 ); IV = blockID128; // Start a LRW session if ((errnum = lrw_start( cipher, IV, Key, (keySizeUnderlying/8), // 128 bits tweak key begins after the // cypher key (Key + (keySizeUnderlying/8)), 0, lrw )) != CRYPT_OK) { status = STATUS_UNSUCCESSFUL; DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to start LRW session (errnum: %d)\n"), errnum)); } else { if (encryptNotDecrypt) { if ((errnum = lrw_encrypt( InData, OutData, InLength, lrw )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to encrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } else { if ((errnum = lrw_decrypt( InData, OutData, InLength, lrw )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to decrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } lrw_done(lrw); } SecZeroMemory(lrw, sizeof(symmetric_LRW)); FREEOTFE_FREE(lrw); break; } case CYPHER_MODE_XTS: { xts = FREEOTFE_MEMALLOC(sizeof(symmetric_xts)); FREEOTFE_MEMZERO(xts, sizeof(symmetric_xts)); // Generate index in correct format // XTS uses: // *) The sector index (i.e. the number of N-bit sectors) // *) The first sector is sector 0 // *) Littleendian format LARGE_INTEGER__To__INTEGER_128_LittleEndian( SectorID, blockID128 ); // Start an XTS session if ((errnum = xts_start( cipher, Key, &(Key[keySizeUnderlying/8]), (keySizeUnderlying/8), 0, xts )) != CRYPT_OK) { status = STATUS_UNSUCCESSFUL; DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to start XTS session (errnum: %d)\n"), errnum)); } else { if (encryptNotDecrypt) { if ((errnum = xts_encrypt( InData, InLength, OutData, blockID128, xts )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to encrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } else { if ((errnum = xts_decrypt( InData, InLength, OutData, blockID128, xts )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to decrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } xts_done(xts); } SecZeroMemory(xts, sizeof(symmetric_xts)); FREEOTFE_FREE(xts); break; } } } DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDecryptData\n"))); return status; }
/** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects Returns CRYPT_OK upon success. */ int xts_test(void) { #ifdef LTC_NO_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key1[32]; unsigned char key2[32]; ulong64 seqnum; unsigned long PTLEN; unsigned char PTX[512], CTX[512]; } tests[] = { /* #1 32 byte key, 32 byte PTX */ { 32, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 32, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x91,0x7c,0xf6,0x9e,0xbd,0x68,0xb2,0xec,0x9b,0x9f,0xe9,0xa3,0xea,0xdd,0xa6,0x92,0xcd,0x43,0xd2,0xf5,0x95,0x98,0xed,0x85,0x8c,0x02,0xc2,0x65,0x2f,0xbf,0x92,0x2e }, }, /* #2, 32 byte key, 32 byte PTX */ { 32, { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11 }, { 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 }, CONST64(0x3333333333), 32, { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, { 0xc4,0x54,0x18,0x5e,0x6a,0x16,0x93,0x6e,0x39,0x33,0x40,0x38,0xac,0xef,0x83,0x8b,0xfb,0x18,0x6f,0xff,0x74,0x80,0xad,0xc4,0x28,0x93,0x82,0xec,0xd6,0xd3,0x94,0xf0 }, }, /* #5 from xts.7, 32 byte key, 32 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 32, { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, { 0xb0,0x1f,0x86,0xf8,0xed,0xc1,0x86,0x37,0x06,0xfa,0x8a,0x42,0x53,0xe3,0x4f,0x28,0xaf,0x31,0x9d,0xe3,0x83,0x34,0x87,0x0f,0x4d,0xd1,0xf9,0x4c,0xbe,0x98,0x32,0xf1 }, }, /* #4, 32 byte key, 512 byte PTX */ { 32, { 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26 }, { 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95 }, 0, 512, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, }, { 0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c, 0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12, 0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce, 0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65, 0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,0xa1,0x0c,0x42,0x11,0x10,0xe6,0xd8,0x15,0x88,0xed,0xe8,0x21,0x03,0xa2,0x52,0xd8, 0xa7,0x50,0xe8,0x76,0x8d,0xef,0xff,0xed,0x91,0x22,0x81,0x0a,0xae,0xb9,0x9f,0x91,0x72,0xaf,0x82,0xb6,0x04,0xdc,0x4b,0x8e,0x51,0xbc,0xb0,0x82,0x35,0xa6,0xf4,0x34, 0x13,0x32,0xe4,0xca,0x60,0x48,0x2a,0x4b,0xa1,0xa0,0x3b,0x3e,0x65,0x00,0x8f,0xc5,0xda,0x76,0xb7,0x0b,0xf1,0x69,0x0d,0xb4,0xea,0xe2,0x9c,0x5f,0x1b,0xad,0xd0,0x3c, 0x5c,0xcf,0x2a,0x55,0xd7,0x05,0xdd,0xcd,0x86,0xd4,0x49,0x51,0x1c,0xeb,0x7e,0xc3,0x0b,0xf1,0x2b,0x1f,0xa3,0x5b,0x91,0x3f,0x9f,0x74,0x7a,0x8a,0xfd,0x1b,0x13,0x0e, 0x94,0xbf,0xf9,0x4e,0xff,0xd0,0x1a,0x91,0x73,0x5c,0xa1,0x72,0x6a,0xcd,0x0b,0x19,0x7c,0x4e,0x5b,0x03,0x39,0x36,0x97,0xe1,0x26,0x82,0x6f,0xb6,0xbb,0xde,0x8e,0xcc, 0x1e,0x08,0x29,0x85,0x16,0xe2,0xc9,0xed,0x03,0xff,0x3c,0x1b,0x78,0x60,0xf6,0xde,0x76,0xd4,0xce,0xcd,0x94,0xc8,0x11,0x98,0x55,0xef,0x52,0x97,0xca,0x67,0xe9,0xf3, 0xe7,0xff,0x72,0xb1,0xe9,0x97,0x85,0xca,0x0a,0x7e,0x77,0x20,0xc5,0xb3,0x6d,0xc6,0xd7,0x2c,0xac,0x95,0x74,0xc8,0xcb,0xbc,0x2f,0x80,0x1e,0x23,0xe5,0x6f,0xd3,0x44, 0xb0,0x7f,0x22,0x15,0x4b,0xeb,0xa0,0xf0,0x8c,0xe8,0x89,0x1e,0x64,0x3e,0xd9,0x95,0xc9,0x4d,0x9a,0x69,0xc9,0xf1,0xb5,0xf4,0x99,0x02,0x7a,0x78,0x57,0x2a,0xee,0xbd, 0x74,0xd2,0x0c,0xc3,0x98,0x81,0xc2,0x13,0xee,0x77,0x0b,0x10,0x10,0xe4,0xbe,0xa7,0x18,0x84,0x69,0x77,0xae,0x11,0x9f,0x7a,0x02,0x3a,0xb5,0x8c,0xca,0x0a,0xd7,0x52, 0xaf,0xe6,0x56,0xbb,0x3c,0x17,0x25,0x6a,0x9f,0x6e,0x9b,0xf1,0x9f,0xdd,0x5a,0x38,0xfc,0x82,0xbb,0xe8,0x72,0xc5,0x53,0x9e,0xdb,0x60,0x9e,0xf4,0xf7,0x9c,0x20,0x3e, 0xbb,0x14,0x0f,0x2e,0x58,0x3c,0xb2,0xad,0x15,0xb4,0xaa,0x5b,0x65,0x50,0x16,0xa8,0x44,0x92,0x77,0xdb,0xd4,0x77,0xef,0x2c,0x8d,0x6c,0x01,0x7d,0xb7,0x38,0xb1,0x8d, 0xeb,0x4a,0x42,0x7d,0x19,0x23,0xce,0x3f,0xf2,0x62,0x73,0x57,0x79,0xa4,0x18,0xf2,0x0a,0x28,0x2d,0xf9,0x20,0x14,0x7b,0xea,0xbe,0x42,0x1e,0xe5,0x31,0x9d,0x05,0x68, } }, /* #7, 32 byte key, 17 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 17, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10 }, { 0x6c,0x16,0x25,0xdb,0x46,0x71,0x52,0x2d,0x3d,0x75,0x99,0x60,0x1d,0xe7,0xca,0x09,0xed }, }, /* #15, 32 byte key, 25 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 25, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18 }, { 0x8f,0x4d,0xcb,0xad,0x55,0x55,0x8d,0x7b,0x4e,0x01,0xd9,0x37,0x9c,0xd4,0xea,0x22,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73 }, }, /* #21, 32 byte key, 31 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 31, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e }, { 0xd0,0x5b,0xc0,0x90,0xa8,0xe0,0x4f,0x1b,0x3d,0x3e,0xcd,0xd5,0xba,0xec,0x0f,0xd4,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73,0x06,0xe6,0x4b,0xe5,0xdd,0x82 }, }, }; unsigned char OUT[512], Torg[16], T[16]; ulong64 seq; symmetric_xts xts; int i, j, k, err, idx; unsigned long len; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (k = 0; k < 4; ++k) { cipher_descriptor[idx].accel_xts_encrypt = NULL; cipher_descriptor[idx].accel_xts_decrypt = NULL; if (k & 0x1) { cipher_descriptor[idx].accel_xts_encrypt = _xts_test_accel_xts_encrypt; } if (k & 0x2) { cipher_descriptor[idx].accel_xts_decrypt = _xts_test_accel_xts_decrypt; } for (j = 0; j < 2; j++) { for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { /* skip the cases where * the length is smaller than 2*blocklen * or the length is not a multiple of 32 */ if ((j == 1) && ((tests[i].PTLEN < 32) || (tests[i].PTLEN % 32))) { continue; } if ((k > 0) && (j == 1)) { continue; } len = tests[i].PTLEN / 2; err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen / 2, 0, &xts); if (err != CRYPT_OK) { return err; } seq = tests[i].seqnum; STORE64L(seq, Torg); XMEMSET(Torg + 8, 0, 8); XMEMCPY(T, Torg, sizeof(T)); if (j == 0) { err = xts_encrypt(tests[i].PTX, tests[i].PTLEN, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } } else { err = xts_encrypt(tests[i].PTX, len, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } err = xts_encrypt(&tests[i].PTX[len], len, &OUT[len], T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } } if (compare_testvector(OUT, tests[i].PTLEN, tests[i].CTX, tests[i].PTLEN, "XTS encrypt", i)) { xts_done(&xts); return CRYPT_FAIL_TESTVECTOR; } XMEMCPY(T, Torg, sizeof(T)); if (j == 0) { err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } } else { err = xts_decrypt(tests[i].CTX, len, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } err = xts_decrypt(&tests[i].CTX[len], len, &OUT[len], T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } } if (compare_testvector(OUT, tests[i].PTLEN, tests[i].PTX, tests[i].PTLEN, "XTS decrypt", i)) { xts_done(&xts); return CRYPT_FAIL_TESTVECTOR; } xts_done(&xts); } } } return CRYPT_OK; #endif }
static void test_xts(const void *opaque) { const QCryptoXTSTestData *data = opaque; unsigned char out[512], Torg[16], T[16]; uint64_t seq; int j; unsigned long len; struct TestAES aesdata; struct TestAES aestweak; for (j = 0; j < 2; j++) { /* skip the cases where * the length is smaller than 2*blocklen * or the length is not a multiple of 32 */ if ((j == 1) && ((data->PTLEN < 32) || (data->PTLEN % 32))) { continue; } len = data->PTLEN / 2; AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.enc); AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.dec); AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.enc); AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.dec); seq = data->seqnum; STORE64L(seq, Torg); memset(Torg + 8, 0, 8); memcpy(T, Torg, sizeof(T)); if (j == 0) { xts_encrypt(&aesdata, &aestweak, test_xts_aes_encrypt, test_xts_aes_decrypt, T, data->PTLEN, out, data->PTX); } else { xts_encrypt(&aesdata, &aestweak, test_xts_aes_encrypt, test_xts_aes_decrypt, T, len, out, data->PTX); xts_encrypt(&aesdata, &aestweak, test_xts_aes_encrypt, test_xts_aes_decrypt, T, len, &out[len], &data->PTX[len]); } g_assert(memcmp(out, data->CTX, data->PTLEN) == 0); memcpy(T, Torg, sizeof(T)); if (j == 0) { xts_decrypt(&aesdata, &aestweak, test_xts_aes_encrypt, test_xts_aes_decrypt, T, data->PTLEN, out, data->CTX); } else { xts_decrypt(&aesdata, &aestweak, test_xts_aes_encrypt, test_xts_aes_decrypt, T, len, out, data->CTX); xts_decrypt(&aesdata, &aestweak, test_xts_aes_encrypt, test_xts_aes_decrypt, T, len, &out[len], &data->CTX[len]); } g_assert(memcmp(out, data->PTX, data->PTLEN) == 0); } }