static int TCRYPT_hdr_from_disk(struct tcrypt_phdr *hdr, struct crypt_params_tcrypt *params, int kdf_index, int cipher_index) { uint32_t crc32; size_t size; /* Check CRC32 of header */ size = TCRYPT_HDR_LEN - sizeof(hdr->d.keys) - sizeof(hdr->d.header_crc32); crc32 = crypt_crc32(~0, (unsigned char*)&hdr->d, size) ^ ~0; if (be16_to_cpu(hdr->d.version) > 3 && crc32 != be32_to_cpu(hdr->d.header_crc32)) { log_dbg("TCRYPT header CRC32 mismatch."); return -EINVAL; } /* Check CRC32 of keys */ crc32 = crypt_crc32(~0, (unsigned char*)hdr->d.keys, sizeof(hdr->d.keys)) ^ ~0; if (crc32 != be32_to_cpu(hdr->d.keys_crc32)) { log_dbg("TCRYPT keys CRC32 mismatch."); return -EINVAL; } /* Convert header to cpu format */ hdr->d.version = be16_to_cpu(hdr->d.version); hdr->d.version_tc = be16_to_cpu(hdr->d.version_tc); hdr->d.keys_crc32 = be32_to_cpu(hdr->d.keys_crc32); hdr->d.hidden_volume_size = be64_to_cpu(hdr->d.hidden_volume_size); hdr->d.volume_size = be64_to_cpu(hdr->d.volume_size); hdr->d.mk_offset = be64_to_cpu(hdr->d.mk_offset); if (!hdr->d.mk_offset) hdr->d.mk_offset = 512; hdr->d.mk_size = be64_to_cpu(hdr->d.mk_size); hdr->d.flags = be32_to_cpu(hdr->d.flags); hdr->d.sector_size = be32_to_cpu(hdr->d.sector_size); if (!hdr->d.sector_size) hdr->d.sector_size = 512; hdr->d.header_crc32 = be32_to_cpu(hdr->d.header_crc32); /* Set params */ params->passphrase = NULL; params->passphrase_size = 0; params->hash_name = tcrypt_kdf[kdf_index].hash; params->key_size = tcrypt_cipher[cipher_index].chain_key_size; params->cipher = tcrypt_cipher[cipher_index].long_name; params->mode = tcrypt_cipher[cipher_index].mode; return 0; }
static int TCRYPT_pool_keyfile(struct crypt_device *cd, unsigned char pool[TCRYPT_KEY_POOL_LEN], const char *keyfile) { unsigned char data[TCRYPT_KEYFILE_LEN]; int i, j, fd, data_size; uint32_t crc; log_dbg("TCRYPT: using keyfile %s.", keyfile); fd = open(keyfile, O_RDONLY); if (fd < 0) { log_err(cd, _("Failed to open key file.\n")); return -EIO; } /* FIXME: add while */ data_size = read(fd, data, TCRYPT_KEYFILE_LEN); close(fd); if (data_size < 0) { log_err(cd, _("Error reading keyfile %s.\n"), keyfile); return -EIO; } for (i = 0, j = 0, crc = ~0U; i < data_size; i++) { crc = crypt_crc32(crc, &data[i], 1); pool[j++] += (unsigned char)(crc >> 24); pool[j++] += (unsigned char)(crc >> 16); pool[j++] += (unsigned char)(crc >> 8); pool[j++] += (unsigned char)(crc); j %= TCRYPT_KEY_POOL_LEN; } memset(&crc, 0, sizeof(crc)); memset(data, 0, TCRYPT_KEYFILE_LEN); return 0; }