diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/smc/Kconfig | 20 | ||||
-rw-r--r-- | security/smc/Makefile | 2 | ||||
-rw-r--r-- | security/smc/s_version.h | 2 | ||||
-rw-r--r-- | security/smc/tf_comm.c | 39 | ||||
-rw-r--r-- | security/smc/tf_crypto_aes.c | 1 | ||||
-rw-r--r-- | security/smc/tf_crypto_rng.c | 169 |
6 files changed, 204 insertions, 29 deletions
diff --git a/security/smc/Kconfig b/security/smc/Kconfig index efab4ee..196da6b 100644 --- a/security/smc/Kconfig +++ b/security/smc/Kconfig @@ -1,6 +1,16 @@ config TF_ZEBRA bool +config TF_CRYPTO_RNG + tristate "Use OMAP4 HW RNG" + depends on ARCH_OMAP4 && m + select SECURITY_MIDDLEWARE_COMPONENT + default n + help + This option enables OMAP4 HW RNG support. + + If you are unsure how to answer this question, answer N. + config SECURITY_MIDDLEWARE_COMPONENT tristate "Enable SMC Driver" depends on ARCH_OMAP3 || ARCH_OMAP4 @@ -21,7 +31,7 @@ config SMC_KERNEL_CRYPTO This option enables crypto subsystem to use SMC and OMAP hardware accelerators. - If you are unsure how to answer this question, answer Y. + If you are unsure how to answer this question, answer N. config SECURE_TRACE bool "Enable SMC secure traces" @@ -31,6 +41,8 @@ config SECURE_TRACE This option enables traces from the SMC Protected Application to be displayed in kernel logs. + If you are unsure how to answer this question, answer Y. + config TF_DRIVER_DEBUG_SUPPORT bool "Debug support" depends on SECURITY_MIDDLEWARE_COMPONENT @@ -38,6 +50,8 @@ config TF_DRIVER_DEBUG_SUPPORT help This options enables debug traces in the driver. + If you are unsure how to answer this question, answer N. + config TF_DRIVER_CRYPTO_FIPS bool "FIPS compliance support" depends on SMC_KERNEL_CRYPTO && ARCH_OMAP4 && MODULE_EXTRA_COPY @@ -47,7 +61,7 @@ config TF_DRIVER_CRYPTO_FIPS cryptographic driver: built-in test vectors for POST, and a device for user space programs to submit more test vectors. - If you are unsure how to answer this question, answer Y. + If you are unsure how to answer this question, answer N. config TF_DRIVER_FAULT_INJECTION bool "Fault injection support" @@ -57,4 +71,4 @@ config TF_DRIVER_FAULT_INJECTION This option allows forcing cryptographic operations in the SMC driver to fail. - If you are unsure how to answer this question, answer Y. + If you are unsure how to answer this question, answer N. diff --git a/security/smc/Makefile b/security/smc/Makefile index ed2de4d..cf79de8 100644 --- a/security/smc/Makefile +++ b/security/smc/Makefile @@ -49,3 +49,5 @@ endif obj-$(CONFIG_SECURITY_MIDDLEWARE_COMPONENT) += tf_driver.o obj-$(CONFIG_SECURITY_MIDDLEWARE_COMPONENT) += rproc_drm.o + +obj-$(CONFIG_TF_CRYPTO_RNG) += tf_crypto_rng.o diff --git a/security/smc/s_version.h b/security/smc/s_version.h index 38a3f1e..016e5de 100644 --- a/security/smc/s_version.h +++ b/security/smc/s_version.h @@ -44,7 +44,7 @@ * If this is a patch or engineering version use the following * defines to set the version number. Else set these values to 0. */ -#define S_VERSION_ENG 1 +#define S_VERSION_ENG 0 #define S_VERSION_PATCH 0 #ifdef S_VERSION_BUILD diff --git a/security/smc/tf_comm.c b/security/smc/tf_comm.c index af4cef6..59733f8 100644 --- a/security/smc/tf_comm.c +++ b/security/smc/tf_comm.c @@ -208,6 +208,7 @@ struct tf_coarse_page_table *tf_alloc_coarse_page_table( } array->type = type; + array->ref_count = 0; INIT_LIST_HEAD(&(array->list)); /* now allocate the actual page the page descriptor describes */ @@ -499,7 +500,7 @@ inline struct page *tf_l2_page_descriptor_to_page(u32 l2_page_descriptor) */ static void tf_get_l2_page_descriptor( u32 *l2_page_descriptor, - u32 flags, struct mm_struct *mm, struct vm_area_struct *vmas) + u32 flags, struct mm_struct *mm) { u32 descriptor; struct page *page; @@ -511,11 +512,6 @@ static void tf_get_l2_page_descriptor( if (*l2_page_descriptor == L2_DESCRIPTOR_FAULT) return; - if (vmas->vm_flags & VM_IO) { - *l2_page_descriptor = L2_DESCRIPTOR_FAULT; - dprintk(KERN_ERR "Memory mapped I/O or similar detected\n"); - return; - } page = (struct page *) (*l2_page_descriptor); descriptor = TF_DEFAULT_COMMON_DESCRIPTORS; @@ -797,8 +793,7 @@ int tf_fill_descriptor_table( tf_get_l2_page_descriptor( &coarse_pg_table->descriptors[j], flags, - current->mm, - vmas[j]); + current->mm); /* * Reject Strongly-Ordered or Device Memory */ @@ -821,18 +816,24 @@ int tf_fill_descriptor_table( goto error; } } - } else if (is_vmalloc_addr((void *)buffer_offset_vaddr)) { - /* Kernel-space memory obtained through vmalloc */ + } else { + /* Kernel-space memory */ dprintk(KERN_INFO "tf_fill_descriptor_table: " - "vmalloc'ed buffer starting at %p\n", + "buffer starting at %p\n", (void *)buffer_offset_vaddr); for (j = page_shift; j < pages_to_get; j++) { struct page *page; void *addr = (void *)(buffer_offset_vaddr + (j - page_shift) * PAGE_SIZE); - page = vmalloc_to_page(addr); + + if (is_vmalloc_addr( + (void *) buffer_offset_vaddr)) + page = vmalloc_to_page(addr); + else + page = virt_to_page(addr); + if (page == NULL) { dprintk(KERN_ERR "tf_fill_descriptor_table: " @@ -849,20 +850,8 @@ int tf_fill_descriptor_table( tf_get_l2_page_descriptor( &coarse_pg_table->descriptors[j], flags, - &init_mm, - vmas[j]); + &init_mm); } - } else { - /* Other kernel-space memory */ - dprintk(KERN_INFO - "tf_fill_descriptor_table: " - "buffer starting at virtual address %p\n", - (void *)buffer_offset_vaddr); - dprintk(KERN_WARNING - "tf_fill_descriptor_table: " - "address type not supported\n"); - ret = -ENOSYS; - goto error; } dmac_flush_range((void *)coarse_pg_table->descriptors, diff --git a/security/smc/tf_crypto_aes.c b/security/smc/tf_crypto_aes.c index 3457e7a..cb340a3 100644 --- a/security/smc/tf_crypto_aes.c +++ b/security/smc/tf_crypto_aes.c @@ -900,6 +900,7 @@ static int aes_dma_stop(struct aes_hwa_ctx *ctx) } else { dma_unmap_sg(NULL, ctx->out_sg, 1, DMA_FROM_DEVICE); dma_unmap_sg(NULL, ctx->in_sg, 1, DMA_TO_DEVICE); + #ifdef CONFIG_TF_DRIVER_FAULT_INJECTION tf_aes_fault_injection(paes_reg->AES_CTRL, sg_virt(ctx->out_sg)); diff --git a/security/smc/tf_crypto_rng.c b/security/smc/tf_crypto_rng.c new file mode 100644 index 0000000..75f61eb --- /dev/null +++ b/security/smc/tf_crypto_rng.c @@ -0,0 +1,169 @@ +/** + * Copyright (c) 2011 Trusted Logic S.A. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/** + * File : tf_crypto_rng.c + * Original-Author : Trusted Logic S.A. (Jeremie Corbier) + * Created : 07-12-2011 + */ + +#include <linux/types.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/hw_random.h> + +#include "tee_client_api.h" + +#define SERVICE_SYSTEM_UUID \ + { 0x56304b83, 0x5c4e, 0x4428, \ + { 0xb9, 0x9e, 0x60, 0x5c, 0x96, 0xae, 0x58, 0xd6 } } + +#define CKF_SERIAL_SESSION 0x00000004 + +#define SERVICE_SYSTEM_PKCS11_C_GENERATERANDOM_COMMAND_ID 0x00000039 +#define SERVICE_SYSTEM_PKCS11_C_OPEN_SESSION_COMMAND_ID 0x00000042 +#define SERVICE_SYSTEM_PKCS11_C_CLOSE_SESSION_COMMAND_ID 0x00000043 + +static struct hwrng tf_crypto_rng; + +static int tf_crypto_rng_read(struct hwrng *rng, void *data, size_t max, + bool wait) +{ + void *buf; + u32 cmd; + u32 crypto_session; + TEEC_Result ret; + TEEC_Operation op; + TEEC_Context teec_context; + TEEC_Session teec_session; + TEEC_UUID uuid = SERVICE_SYSTEM_UUID; + int err = 0; + + buf = kmalloc(max, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + ret = TEEC_InitializeContext(NULL, &teec_context); + if (ret != TEEC_SUCCESS) { + kfree(buf); + return -EFAULT; + } + + /* Call C_OpenSession */ + memset(&op, 0, sizeof(TEEC_Operation)); + + op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, + TEEC_NONE); + + ret = TEEC_OpenSession(&teec_context, &teec_session, + &uuid, TEEC_LOGIN_PUBLIC, NULL, &op, NULL); + if (ret != TEEC_SUCCESS) { + kfree(buf); + TEEC_FinalizeContext(&teec_context); + return -EFAULT; + } + + memset(&op, 0, sizeof(TEEC_Operation)); + + op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, + TEEC_NONE); + op.params[0].value.a = 0; + op.params[0].value.b = CKF_SERIAL_SESSION; + + cmd = SERVICE_SYSTEM_PKCS11_C_OPEN_SESSION_COMMAND_ID & 0x00007FFF; + + ret = TEEC_InvokeCommand(&teec_session, cmd, &op, NULL); + if (ret != TEEC_SUCCESS) { + printk(KERN_ERR "%s: TEEC_InvokeCommand returned 0x%08x\n", + __func__, ret); + err = -EFAULT; + goto exit; + } + + crypto_session = op.params[0].value.a; + + /* Call C_GenerateRandom */ + memset(&op, 0, sizeof(TEEC_Operation)); + + op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, + TEEC_NONE, TEEC_NONE, TEEC_NONE); + op.params[0].tmpref.buffer = (uint8_t *) buf; + op.params[0].tmpref.size = (uint32_t) max; + + cmd = (crypto_session << 16) | + (SERVICE_SYSTEM_PKCS11_C_GENERATERANDOM_COMMAND_ID & 0x7fff); + + ret = TEEC_InvokeCommand(&teec_session, cmd, &op, NULL); + if (ret != TEEC_SUCCESS) { + printk(KERN_ERR "%s: TEEC_InvokeCommand returned 0x%08x\n", + __func__, ret); + err = -EFAULT; + } + + /* Call C_CloseSession */ + memset(&op, 0, sizeof(TEEC_Operation)); + + op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, + TEEC_NONE); + + cmd = (crypto_session << 16) | + (SERVICE_SYSTEM_PKCS11_C_CLOSE_SESSION_COMMAND_ID & 0x7fff); + + ret = TEEC_InvokeCommand(&teec_session, cmd, &op, NULL); + if (ret != TEEC_SUCCESS) { + printk(KERN_ERR "%s: TEEC_InvokeCommand returned 0x%08x\n", + __func__, ret); + err = -EFAULT; + } + +exit: + TEEC_CloseSession(&teec_session); + TEEC_FinalizeContext(&teec_context); + + if (!err) + memcpy(data, buf, max); + + kfree(buf); + + if (err) + return err; + else + return max; +} + +static int __init tf_crypto_rng_init(void) +{ + memset(&tf_crypto_rng, 0, sizeof(struct hwrng)); + + tf_crypto_rng.name = "rng-smc"; + tf_crypto_rng.read = tf_crypto_rng_read; + + return hwrng_register(&tf_crypto_rng); +} +module_init(tf_crypto_rng_init); + +static void __exit tf_crypto_rng_exit(void) +{ + hwrng_unregister(&tf_crypto_rng); +} +module_exit(tf_crypto_rng_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jeremie Corbier <jeremie.corbier@trusted-logic.com>"); +MODULE_DESCRIPTION("OMAP4 TRNG driver."); |