| #include "../include/phynand.h" |
| #ifndef AML_NAND_UBOOT |
| #include <linux/module.h> |
| #include <linux/types.h> |
| #include <linux/init.h> |
| #include <linux/kernel.h> |
| #include <linux/string.h> |
| #include <linux/ioport.h> |
| #include <linux/platform_device.h> |
| #include <linux/delay.h> |
| #include <linux/err.h> |
| #include <linux/slab.h> |
| #include <linux/io.h> |
| #include <linux/bitops.h> |
| #include <linux/crc32.h> |
| #include <linux/fs.h> |
| #include <asm/uaccess.h> |
| #include <linux/amlogic/securitykey.h> |
| #endif |
| |
| extern int amlnand_read_info_by_name(struct amlnand_chip *aml_chip,u8 * info,u8 * buf, u8 * name,unsigned size); |
| extern int amlnand_save_info_by_name(struct amlnand_chip *aml_chip,u8 * info,u8 * buf, u8 * name,unsigned size); |
| extern int amlnand_info_init(struct amlnand_chip *aml_chip, u8 * info,u8 * buf, u8 *name,unsigned size); |
| |
| //#define KEYSIZE (CONFIG_KEYSIZE - (sizeof(uint32_t))) |
| |
| static struct amlnand_chip *aml_chip_key = NULL; |
| |
| int aml_nand_update_key(struct amlnand_chip * aml_chip, char *key_ptr) |
| { |
| int ret = 0; |
| int malloc_flag = 0; |
| char *key_buf = NULL; |
| |
| if (key_buf == NULL) { |
| |
| key_buf = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL); |
| malloc_flag = 1; |
| if (key_buf == NULL) |
| return -ENOMEM; |
| memset(key_buf,0,CONFIG_KEYSIZE); |
| ret = amlnand_read_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_buf,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE); |
| if (ret) { |
| aml_nand_msg("read key error,%s\n",__func__); |
| ret = -EFAULT; |
| goto exit; |
| } |
| }else{ |
| key_buf = key_ptr; |
| } |
| |
| aml_nand_msg("aml_chip->nand_key : arg_type%d valid %d,update_flag %d,valid_blk_addr %d,valid_page_addr %d",aml_chip->nand_key.arg_type,aml_chip->nand_key.arg_valid,\ |
| aml_chip->nand_key.update_flag,aml_chip->nand_key.valid_blk_addr,aml_chip->nand_key.valid_page_addr); |
| |
| ret = amlnand_save_info_by_name( aml_chip,(u8 *)&(aml_chip->nand_key),(u8 *)key_buf, (u8 *)KEY_INFO_HEAD_MAGIC,CONFIG_KEYSIZE); |
| if (ret < 0) { |
| aml_nand_msg("aml_nand_update_key : save key info failed"); |
| } |
| |
| exit: |
| if (malloc_flag &&(key_buf)) { |
| kfree(key_buf); |
| key_buf = NULL; |
| } |
| return 0; |
| } |
| |
| /* |
| * This funcion reads the u-boot keyionment variables. |
| * The f_pos points directly to the key location. |
| */ |
| static int nand_key_read(struct aml_keybox_provider_s * provider, u8 * buf, int len, int flags) |
| { |
| struct amlnand_chip * aml_chip = provider->priv; |
| struct nand_menson_key *key_ptr = NULL; |
| //int error = 0,i=0; |
| int error = 0; |
| if (len > CONFIG_KEYSIZE) |
| { |
| printk("key data len too much,%s\n",__func__); |
| return -EFAULT; |
| } |
| key_ptr = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL); |
| if (key_ptr == NULL) |
| return -ENOMEM; |
| memset(key_ptr, 0, CONFIG_KEYSIZE); |
| |
| error = amlnand_read_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key), (u8 *)key_ptr, (u8*)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE); |
| //error = aml_nand_read_key(aml_chip, (u_char *)key_ptr); |
| if (error) |
| { |
| printk("read key error,%s\n",__func__); |
| error = -EFAULT; |
| goto exit; |
| } |
| memcpy(buf, key_ptr->data, len); |
| |
| exit: |
| kfree(key_ptr); |
| return 0; |
| } |
| |
| static int nand_key_write(struct aml_keybox_provider_s * provider, u8 *buf,int len) |
| { |
| struct amlnand_chip * aml_chip = provider->priv; |
| struct nand_menson_key *key_ptr = NULL; |
| //int error = 0,i=0; |
| int error = 0; |
| |
| if (len > CONFIG_KEYSIZE) |
| { |
| printk("key data len too much,%s\n",__func__); |
| return -EFAULT; |
| } |
| key_ptr = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL); |
| if (key_ptr == NULL) |
| return -ENOMEM; |
| memset(key_ptr,0,CONFIG_KEYSIZE); |
| memcpy(key_ptr->data + 0, buf, len); |
| |
| error = amlnand_save_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE); |
| if (error) |
| { |
| printk("save key error,%s\n",__func__); |
| error = -EFAULT; |
| goto exit; |
| } |
| exit: |
| kfree(key_ptr); |
| return error; |
| } |
| |
| static struct aml_keybox_provider_s nand_provider={ |
| .name="nand_key", |
| .read=nand_key_read, |
| .write=nand_key_write, |
| }; |
| |
| int aml_key_init(struct amlnand_chip *aml_chip) |
| { |
| int ret = 0; |
| struct nand_menson_key *key_ptr = NULL; |
| struct aml_keybox_provider_s * provider; |
| |
| key_ptr = aml_nand_malloc(CONFIG_KEYSIZE); |
| if (key_ptr == NULL) { |
| aml_nand_msg("nand malloc for key_ptr failed"); |
| ret = -1; |
| goto exit_error0; |
| } |
| memset(key_ptr,0x0,CONFIG_KEYSIZE); |
| aml_nand_msg("nand key: nand_key_probe. "); |
| |
| ret = amlnand_info_init(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE); |
| if (ret < 0) { |
| aml_nand_msg("invalid nand key\n"); |
| } |
| |
| aml_chip_key = aml_chip; |
| nand_provider.priv=aml_chip_key; |
| |
| provider = aml_keybox_provider_get(nand_provider.name); |
| if (provider) { |
| return ret; |
| } |
| |
| ret = aml_keybox_provider_register(&nand_provider); |
| if (ret) { |
| BUG(); |
| } |
| |
| exit_error0: |
| if (key_ptr) { |
| aml_nand_free(key_ptr); |
| key_ptr =NULL; |
| } |
| return ret; |
| } |
| #ifdef AML_NAND_UBOOT |
| int nandkey_provider_register(void) |
| { |
| int ret = 0; |
| #if 0 |
| ret = aml_keybox_provider_register(&nand_provider); |
| if (ret) { |
| BUG(); |
| } |
| #endif |
| return ret; |
| } |
| #endif |
| |