BCH: Add configurable AES encryption support to block-to-character (BCH) driver. This allows any block device to be accessed as an encrypted character device. From Max Nekludov

This commit is contained in:
Gregory Nutt 2014-07-07 08:00:00 -06:00
parent edba505fc2
commit dc7bcb0c1d
5 changed files with 106 additions and 3 deletions

View File

@ -2,3 +2,13 @@
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config BCH_ENCRYPTION
bool "Enable encryption feature"
default n
depends on CRYPTO_AES
config BCH_ENCRYPTION_KEY_SIZE
int "AES key size"
default 16
depends on BCH_ENCRYPTION

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/bch/bch_internal.h
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -70,6 +70,10 @@ struct bchlib_s
bool dirty; /* Data has been written to the buffer */
bool readonly; /* true: Only read operations are supported */
FAR uint8_t *buffer; /* One sector buffer */
#if defined(CONFIG_BCH_ENCRYPTION)
uint8_t key[CONFIG_BCH_ENCRYPTION_KEY_SIZE]; /* Encryption key */
#endif
};
/****************************************************************************

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/bch/bchdev_driver.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -186,6 +186,7 @@ static ssize_t bch_read(FAR struct file *filep, FAR char *buffer, size_t len)
{
filep->f_pos += len;
}
bchlib_semgive(bch);
return ret;
}
@ -249,6 +250,13 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
bchlib_semgive(bch);
}
#if defined(CONFIG_BCH_ENCRYPTION)
else if (cmd == DIOC_SETKEY)
{
memcpy(bch->key, (void*)arg, CONFIG_BCH_ENCRYPTION_KEY_SIZE);
ret = OK;
}
#endif
return ret;
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/bch/bchlib_cache.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -49,6 +49,10 @@
#include "bch_internal.h"
#if defined(CONFIG_BCH_ENCRYPTION)
# include <crypto/crypto.h>
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@ -65,6 +69,51 @@
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: bch_xor
****************************************************************************/
#if defined(CONFIG_BCH_ENCRYPTION)
static void bch_xor(uint32_t *R, uint32_t *A, uint32_t *B)
{
R[0] = A[0] ^ B[0];
R[1] = A[1] ^ B[1];
R[2] = A[2] ^ B[2];
R[3] = A[3] ^ B[3];
}
#endif
/****************************************************************************
* Name: bch_cypher
****************************************************************************/
#if defined(CONFIG_BCH_ENCRYPTION)
static int bch_cypher(FAR struct bchlib_s *bch, int encrypt)
{
int blocks = bch->sectsize / 16;
uint32_t *buffer = (uint32_t*)bch->buffer;
int i;
for (i = 0; i < blocks; i++, buffer += 16 / sizeof(uint32_t) )
{
uint32_t T[4];
uint32_t X[4] = {bch->sector, 0, 0, i};
aes_cypher(X, X, 16, NULL, bch->key, CONFIG_BCH_ENCRYPTION_KEY_SIZE,
AES_MODE_ECB, CYPHER_ENCRYPT);
/* Xor-Encrypt-Xor */
bch_xor(T, X, buffer);
aes_cypher(T, T, 16, NULL, bch->key, CONFIG_BCH_ENCRYPTION_KEY_SIZE,
AES_MODE_ECB, encrypt);
bch_xor(buffer, X, T);
}
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -85,16 +134,41 @@ int bchlib_flushsector(FAR struct bchlib_s *bch)
FAR struct inode *inode;
ssize_t ret = OK;
/* Check if the sector has been modified and is out of synch with the
* media.
*/
if (bch->dirty)
{
inode = bch->inode;
#if defined(CONFIG_BCH_ENCRYPTION)
/* Encrypt data as necessary */
bch_cypher(bch, CYPHER_ENCRYPT);
#endif
/* Write the sector to the media */
ret = inode->u.i_bops->write(inode, bch->buffer, bch->sector, 1);
if (ret < 0)
{
fdbg("Write failed: %d\n");
}
#if defined(CONFIG_BCH_ENCRYPTION)
/* Computation overhead to save memory for extra sector buffer
* TODO: Add configuration switch for extra sector buffer
*/
bch_cypher(bch, CYPHER_DECRYPT);
#endif
/* The sector is now in sync with the media */
bch->dirty = false;
}
return (int)ret;
}
@ -127,6 +201,9 @@ int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector)
fdbg("Read failed: %d\n");
}
bch->sector = sector;
#if defined(CONFIG_BCH_ENCRYPTION)
bch_cypher(bch, CYPHER_DECRYPT);
#endif
}
return (int)ret;
}

View File

@ -143,6 +143,10 @@
* FIOC_GETPRIV released.
*/
#define DIOC_SETKEY _DIOC(0X0004) /* IN: Encryption key
* OUT: None
*/
/* NuttX block driver ioctl definitions *************************************/
#define _BIOCVALID(c) (_IOC_TYPE(c)==_BIOCBASE)