Skip to content

Commit

Permalink
first step to porting to linux; can be broken :)
Browse files Browse the repository at this point in the history
  • Loading branch information
bwalex committed Jul 20, 2011
1 parent 12b9b59 commit 34165ed
Show file tree
Hide file tree
Showing 11 changed files with 463 additions and 28 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ WARNFLAGS= -Wsystem-headers -Werror -Wall -W -Wno-unused-parameter \
-Wswitch -Wshadow -Wcast-align -Wunused-parameter -Wchar-subscripts \
-Winline -Wnested-externs -Wredundant-decls

# for linux...
WARNFLAGS= -Wall

linux:
gcc -O0 $(WARNFLAGS) -g main.c tcplay.c crc32.c safe_mem.c io.c crypto-gcrypt.c hdr.c humanize.c -o tc-play -lcrypto -ldevmapper -luuid
all:
gcc -O0 $(WARNFLAGS) -g main.c tcplay.c crc32.c safe_mem.c io.c crypto-dev.c hdr.c -o tc-play -lcrypto -ldevmapper -lprop -lutil
gcc -O0 $(WARNFLAGS) -g main.c tcplay.c crc32.c safe_mem.c io.c crypto-dev.c hdr.c humanize.c -o tc-play -lcrypto -ldevmapper -lprop -lutil
lib:
gcc $(WARNFLAGS) -c -fPIC -O0 -Wall -g tcplay_api.c tcplay.c crc32.c safe_mem.c io.c crypto-dev.c hdr.c
gcc -shared -Wl,-version-script=tcplay.map -o libtcplay.so tcplay_api.o tcplay.o crc32.o safe_mem.o io.o crypto-dev.o hdr.o
Expand Down
2 changes: 2 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
A Linux port is underway.

*NOTE* tcplay has now been integrated into DragonFly BSD, it's actual home. I'll
try to keep the version up here up to date, but I can't make any promises. For
the newest version, check out DragonFly BSD and look into sbin/tcplay and
Expand Down
1 change: 1 addition & 0 deletions crc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
*/

#include <stdlib.h>
#include <stdint.h>
#include "crc32.h"

uint32_t crc32_tab[] = {
Expand Down
2 changes: 1 addition & 1 deletion crc32.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
uint32_t crc32(const void *buf, size_t size);
uint32_t crc32_intermediate(uint32_t crc, uint8_t d);
uint32_t crc32_intermediate(uint32_t crc, uint8_t d);
325 changes: 325 additions & 0 deletions crypto-gcrypt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
/*
* Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#if defined(__linux__)
#define _GNU_SOURCE
#define __USE_GNU
#endif

#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/sysctl.h>

#include <fcntl.h>
//#include <unistd.h>
#include <inttypes.h>
#include <errno.h>
#include <string.h>
#include <openssl/evp.h>

#include "crc32.h"
#include "tcplay.h"


static
int
get_cryptodev_cipher_id(struct tc_crypto_algo *cipher)
{
#if 0
if (strcmp(cipher->name, "AES-128-XTS") == 0)
return CRYPTO_AES_XTS;
else if (strcmp(cipher->name, "AES-256-XTS") == 0)
return CRYPTO_AES_XTS;
else if (strcmp(cipher->name, "TWOFISH-128-XTS") == 0)
return CRYPTO_TWOFISH_XTS;
else if (strcmp(cipher->name, "TWOFISH-256-XTS") == 0)
return CRYPTO_TWOFISH_XTS;
else if (strcmp(cipher->name, "SERPENT-128-XTS") == 0)
return CRYPTO_SERPENT_XTS;
else if (strcmp(cipher->name, "SERPENT-256-XTS") == 0)
return CRYPTO_SERPENT_XTS;
else
#endif
return -1;
}

int
tc_crypto_init(void)
{
OpenSSL_add_all_algorithms();

return 0;
}

int
tc_cipher_chain_populate_keys(struct tc_cipher_chain *cipher_chain,
unsigned char *key)
{
int total_key_bytes, used_key_bytes;
struct tc_cipher_chain *dummy_chain;

/*
* We need to determine the total key bytes as the key locations
* depend on it.
*/
total_key_bytes = 0;
for (dummy_chain = cipher_chain;
dummy_chain != NULL;
dummy_chain = dummy_chain->next) {
total_key_bytes += dummy_chain->cipher->klen;
}

/*
* Now we need to get prepare the keys, as the keys are in
* forward order with respect to the cipher cascade, but
* the actual decryption is in reverse cipher cascade order.
*/
used_key_bytes = 0;
for (dummy_chain = cipher_chain;
dummy_chain != NULL;
dummy_chain = dummy_chain->next) {
dummy_chain->key = alloc_safe_mem(dummy_chain->cipher->klen);
if (dummy_chain->key == NULL) {
tc_log(1, "tc_decrypt: Could not allocate key "
"memory\n");
return ENOMEM;
}

/* XXX: here we assume XTS operation! */
memcpy(dummy_chain->key,
key + used_key_bytes/2,
dummy_chain->cipher->klen/2);
memcpy(dummy_chain->key + dummy_chain->cipher->klen/2,
key + (total_key_bytes/2) + used_key_bytes/2,
dummy_chain->cipher->klen/2);

/* Remember how many key bytes we've seen */
used_key_bytes += dummy_chain->cipher->klen;
}

return 0;
}

int
tc_encrypt(struct tc_cipher_chain *cipher_chain, unsigned char *key,
unsigned char *iv,
unsigned char *in, int in_len, unsigned char *out)
{
int cipher_id;
int err;

if ((err = tc_cipher_chain_populate_keys(cipher_chain, key)))
return err;

#ifdef DEBUG
printf("tc_encrypt: starting chain\n");
#endif

/*
* Now process the actual decryption, in forward cascade order.
*/
for (;
cipher_chain != NULL;
cipher_chain = cipher_chain->next) {
cipher_id = get_cryptodev_cipher_id(cipher_chain->cipher);
if (cipher_id < 0) {
tc_log(1, "Cipher %s not found\n",
cipher_chain->cipher->name);
return ENOENT;
}

#ifdef DEBUG
printf("tc_encrypt: Currently using cipher %s\n",
cipher_chain->cipher->name);
#endif

#if 0
err = syscrypt(cipher_id, cipher_chain->key,
cipher_chain->cipher->klen, iv, in, out, in_len, 1);
#endif

/* Deallocate this key, since we won't need it anymore */
free_safe_mem(cipher_chain->key);

if (err != 0)
return err;

/* Set next input buffer as current output buffer */
in = out;
}

return 0;
}

int
tc_decrypt(struct tc_cipher_chain *cipher_chain, unsigned char *key,
unsigned char *iv,
unsigned char *in, int in_len, unsigned char *out)
{
int cipher_id;
int err;

if ((err = tc_cipher_chain_populate_keys(cipher_chain, key)))
return err;

#ifdef DEBUG
printf("tc_decrypt: starting chain!\n");
#endif

/*
* Now process the actual decryption, in reverse cascade order; so
* first find the last element in the chain.
*/
for (; cipher_chain->next != NULL; cipher_chain = cipher_chain->next)
;
for (;
cipher_chain != NULL;
cipher_chain = cipher_chain->prev) {
cipher_id = get_cryptodev_cipher_id(cipher_chain->cipher);
if (cipher_id < 0) {
tc_log(1, "Cipher %s not found\n",
cipher_chain->cipher->name);
return ENOENT;
}

#ifdef DEBUG
printf("tc_decrypt: Currently using cipher %s\n",
cipher_chain->cipher->name);
#endif

#if 0
err = syscrypt(cipher_id, cipher_chain->key,
cipher_chain->cipher->klen, iv, in, out, in_len, 0);
#endif

/* Deallocate this key, since we won't need it anymore */
free_safe_mem(cipher_chain->key);

if (err != 0)
return err;

/* Set next input buffer as current output buffer */
in = out;
}

return 0;
}

int
pbkdf2(const char *pass, int passlen, const unsigned char *salt, int saltlen,
int iter, const char *hash_name, int keylen, unsigned char *out)
{
const EVP_MD *md;
int r;

md = EVP_get_digestbyname(hash_name);
if (md == NULL) {
printf("Hash %s not found\n", hash_name);
return ENOENT;
}
r = PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, md,
keylen, out);

if (r == 0) {
printf("Error in PBKDF2\n");
return EINVAL;
}

return 0;
}

int
apply_keyfiles(unsigned char *pass, size_t pass_memsz, const char *keyfiles[],
int nkeyfiles)
{
int pl, k;
unsigned char *kpool;
unsigned char *kdata;
int kpool_idx;
size_t i, kdata_sz;
uint32_t crc;

if (pass_memsz < MAX_PASSSZ) {
tc_log(1, "Not enough memory for password manipluation\n");
return ENOMEM;
}

pl = strlen(pass);
memset(pass+pl, 0, MAX_PASSSZ-pl);

if ((kpool = alloc_safe_mem(KPOOL_SZ)) == NULL) {
tc_log(1, "Error allocating memory for keyfile pool\n");
return ENOMEM;
}

memset(kpool, 0, KPOOL_SZ);

for (k = 0; k < nkeyfiles; k++) {
#ifdef DEBUG
printf("Loading keyfile %s into kpool\n", keyfiles[k]);
#endif
kpool_idx = 0;
crc = ~0U;
kdata_sz = MAX_KFILE_SZ;

if ((kdata = read_to_safe_mem(keyfiles[k], 0, &kdata_sz)) == NULL) {
tc_log(1, "Error reading keyfile %s content\n",
keyfiles[k]);
free_safe_mem(kpool);
return EIO;
}

for (i = 0; i < kdata_sz; i++) {
crc = crc32_intermediate(crc, kdata[i]);

kpool[kpool_idx++] += (unsigned char)(crc >> 24);
kpool[kpool_idx++] += (unsigned char)(crc >> 16);
kpool[kpool_idx++] += (unsigned char)(crc >> 8);
kpool[kpool_idx++] += (unsigned char)(crc);

/* Wrap around */
if (kpool_idx == KPOOL_SZ)
kpool_idx = 0;
}

free_safe_mem(kdata);
}

#ifdef DEBUG
printf("Applying kpool to passphrase\n");
#endif
/* Apply keyfile pool to passphrase */
for (i = 0; i < KPOOL_SZ; i++)
pass[i] += kpool[i];

free_safe_mem(kpool);

return 0;
}
12 changes: 12 additions & 0 deletions hdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,23 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#if defined(__linux__)
#define _GNU_SOURCE
#define __USE_GNU
#endif

#include <sys/types.h>

#if defined(__DragonFly__)
#include <sys/endian.h>
#elif defined(__linux__)
#include <endian.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>

#include "crc32.h"
Expand Down
Loading

0 comments on commit 34165ed

Please sign in to comment.