int sec_dev_read_secroimg(void) { int ret = SEC_OK; uint32 search_offset = SECRO_SEARCH_START; uint32 search_len = SECRO_SEARCH_LEN; uint32 mtd_num; uint32 mtd_off = SECRO_SEARCH_START; const uint32 img_len = rom_info.m_sec_ro_length; const uint32 cipher_len = sizeof(AND_AC_ANDRO_T) + sizeof(AND_AC_MD_T)+ sizeof(AND_AC_MD2_T); /* ------------------------ */ /* check status */ /* ------------------------ */ if(0 == secro_img_mtd_num) { ret = ERR_SECROIMG_PART_NOT_FOUND; goto _end; } mtd_num = secro_img_mtd_num; /* ------------------------ */ /* check parameter */ /* ------------------------ */ if(0 == img_len) { ret = ERR_SECROIMG_INVALID_IMG_LEN; goto _end; } if(img_len != sizeof(secroimg)) { ret = ERR_SECROIMG_LEN_INCONSISTENT_WITH_PL; goto _end; } SMSG(TRUE,"[%s] SECRO image len '0x%x'\n",MOD, sizeof(secroimg)); /* ------------------------ */ /* find ac region */ /* ------------------------ */ /* read 1MB nand flash data to search rom info */ for(search_offset = SECRO_SEARCH_START; search_offset < (search_len + SECRO_SEARCH_START); search_offset += SECRO_SEARCH_REGION) { /* search partition */ if(mtd_off < mtd_part_map[mtd_num].sz) { if(FALSE == dump_secro_info) { SMSG(TRUE,"dev %2d, 0x%08x, 0x%08x\n", mtd_num, mtd_off, search_offset); dump_secro_info = TRUE; } /* ------------------------ */ /* search secro image */ /* ------------------------ */ ret = read_info (mtd_num, mtd_off, SECRO_SEARCH_REGION, ROM_SEC_AC_REGION_ID, ROM_SEC_AC_REGION_ID_LEN, img_len, (uchar*)&secroimg); if(SEC_OK == ret) { SMSG(TRUE,"[%s] SECRO img is found (lock)\n",MOD); /* ------------------------ */ /* decrypt secro image */ /* ------------------------ */ osal_secro_lock(); dump_buf((uchar*)&secroimg.m_andro,0x4); if(TRUE == sec_secro_ac()) { sp_hacc_dec((uchar*)&secroimg.m_andro, cipher_len, TRUE,HACC_USER1,TRUE); } dump_buf((uchar*)&secroimg.m_andro,0x4); /* ------------------------ */ /* check integrity */ /* ------------------------ */ if(SEC_OK != (ret = sec_secro_check())) { osal_secro_unlock(); goto _end; } /* ------------------------ */ /* encrypt secro image */ /* ------------------------ */ if(TRUE == sec_secro_ac()) { sp_hacc_enc((uchar*)&secroimg.m_andro, cipher_len, TRUE,FALSE,TRUE); } dump_buf((uchar*)&secroimg.m_andro,0x4); /* ------------------------ */ /* SECROIMG is valid */ /* ------------------------ */ bSecroExist = TRUE; osal_secro_unlock(); goto _end; } } /* next should move to next partition ? */ if(search_offset >= mtd_part_map[mtd_num+1].off) { mtd_num ++; mtd_off = 0; search_offset -= SECRO_SEARCH_REGION; } else { mtd_off += SECRO_SEARCH_REGION; } } ret = ERR_SECROIMG_MTD_NOT_FOUND; _end: return ret; }
/************************************************************************** * SEC DRIVER IOCTL **************************************************************************/ long sec_core_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; int ret = 0; unsigned int cipher_len = 0; unsigned int rid[4]; unsigned char part_name[10]; META_CONTEXT meta_ctx; /* ---------------------------------- */ /* IOCTL */ /* ---------------------------------- */ if (_IOC_TYPE(cmd) != SEC_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > SEC_IOC_MAXNR) return -ENOTTY; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; switch (cmd) { /* ---------------------------------- */ /* get random id */ /* ---------------------------------- */ case SEC_GET_RANDOM_ID: SMSG(bMsg,"[%s] CMD - SEC_GET_RANDOM_ID\n",MOD); sec_get_random_id(&rid[0]); ret = osal_copy_to_user((void __user *)arg, (void *)&rid[0], sizeof(unsigned int) * 4); break; /* ---------------------------------- */ /* init boot info */ /* ---------------------------------- */ case SEC_BOOT_INIT: SMSG(bMsg,"[%s] CMD - SEC_BOOT_INIT\n",MOD); ret = sec_boot_init(); ret = osal_copy_to_user((void __user *)arg, (void *)&ret, sizeof(int)); break; /* ---------------------------------- */ /* check if secure boot is enbaled */ /* ---------------------------------- */ case SEC_BOOT_IS_ENABLED: SMSG(bMsg,"[%s] CMD - SEC_BOOT_IS_ENABLED\n",MOD); ret = sec_boot_enabled(); ret = osal_copy_to_user((void __user *)arg, (void *)&ret, sizeof(int)); break; /* ---------------------------------- */ /* encrypt sec cfg */ /* ---------------------------------- */ case SEC_SECCFG_ENCRYPT: SMSG(bMsg,"[%s] CMD - SEC_SECCFG_ENCRYPT\n",MOD); if(copy_from_user((void *)&seccfg, (void __user *)arg, sizeof(SECCFG_U))) { return -EFAULT; } /* specify encrpytion length */ SMSG(true,"[%s] SECCFG v%d\n",MOD,get_seccfg_ver()); if (SEC_CFG_END_PATTERN == seccfg.v1.end_pattern) { if((SECCFG_V1 != get_seccfg_ver()) && (SECCFG_V1_2 != get_seccfg_ver())) { SMSG(true,"[%s] mismatch seccfg version v%d\n",MOD,get_seccfg_ver()); SEC_ASSERT(0); } cipher_len = get_seccfg_cipher_len(); sp_hacc_enc((unsigned char*)&seccfg.v1.image_info,cipher_len,rom_info.m_SEC_CTRL.m_seccfg_ac_en,HACC_USER1,FALSE); } else if (SEC_CFG_END_PATTERN == seccfg.v3.end_pattern) { if(SECCFG_V3 != get_seccfg_ver()) { SMSG(true,"[%s] mismatch seccfg version v%d\n",MOD,get_seccfg_ver()); SEC_ASSERT(0); } cipher_len = get_seccfg_cipher_len(); sp_hacc_enc((unsigned char*)&seccfg.v3.image_info,cipher_len,rom_info.m_SEC_CTRL.m_seccfg_ac_en,HACC_USER1,FALSE); } else { SMSG(true,"[%s] wrong seccfg version v%d\n",MOD,seccfg.v3.seccfg_ver) SEC_ASSERT(0); } ret = osal_copy_to_user((void __user *)arg, (void *)&seccfg, sizeof(SECCFG_U)); break; /* ---------------------------------- */ /* decrypt sec cfg */ /* ---------------------------------- */ case SEC_SECCFG_DECRYPT: SMSG(bMsg,"[%s] CMD - SEC_SECCFG_DECRYPT\n",MOD); if(copy_from_user((void *)&seccfg, (void __user *)arg, sizeof(SECCFG_U))) { return -EFAULT; } /* specify decrpytion length */ if (SEC_CFG_END_PATTERN == seccfg.v1.end_pattern) { /* seccfg version should be corrected by caller */ set_seccfg_ver(SECCFG_V1); cipher_len = get_seccfg_cipher_len(); sp_hacc_dec((unsigned char*)&seccfg.v1.image_info,cipher_len,rom_info.m_SEC_CTRL.m_seccfg_ac_en,HACC_USER1,FALSE); } else if (SEC_CFG_END_PATTERN == seccfg.v3.end_pattern) { /* seccfg version should be corrected by caller */ set_seccfg_ver(SECCFG_V3); cipher_len = get_seccfg_cipher_len(); sp_hacc_dec((unsigned char*)&seccfg.v3.image_info,cipher_len,rom_info.m_SEC_CTRL.m_seccfg_ac_en,HACC_USER1,FALSE); } else { SMSG(true,"[%s] wrong seccfg version v%d\n",MOD,seccfg.v3.seccfg_ver) SEC_ASSERT(0); } SMSG(bMsg,"[%s] SECCFG v%d\n",MOD,get_seccfg_ver()); ret = osal_copy_to_user((void __user *)arg, (void *)&seccfg, sizeof(SECCFG_U)); break; /* ---------------------------------- */ /* NVRAM HW encryption */ /* ---------------------------------- */ case SEC_NVRAM_HW_ENCRYPT: SMSG(bMsg,"[%s] CMD - SEC_NVRAM_HW_ENCRYPT\n",MOD); if(osal_copy_from_user((void *)&meta_ctx, (void __user *)arg, sizeof(meta_ctx))) { return -EFAULT; } /* TODO : double check if META register is correct ? */ sp_hacc_enc((unsigned char*)&(meta_ctx.data),NVRAM_CIPHER_LEN,TRUE,HACC_USER2,FALSE); meta_ctx.ret = SEC_OK; ret = osal_copy_to_user((void __user *)arg, (void *)&meta_ctx, sizeof(meta_ctx)); break; /* ---------------------------------- */ /* NVRAM HW decryption */ /* ---------------------------------- */ case SEC_NVRAM_HW_DECRYPT: SMSG(bMsg,"[%s] CMD - SEC_NVRAM_HW_DECRYPT\n",MOD); if(osal_copy_from_user((void *)&meta_ctx, (void __user *)arg, sizeof(meta_ctx))) { return -EFAULT; } sp_hacc_dec((unsigned char*)&(meta_ctx.data),NVRAM_CIPHER_LEN,TRUE,HACC_USER2,FALSE); meta_ctx.ret = SEC_OK; ret = osal_copy_to_user((void __user *)arg, (void *)&meta_ctx, sizeof(meta_ctx)); break; /* ---------------------------------- */ /* check if secure usbdl is enbaled */ /* ---------------------------------- */ case SEC_USBDL_IS_ENABLED: SMSG(bMsg,"[%s] CMD - SEC_USBDL_IS_ENABLED\n",MOD); ret = sec_usbdl_enabled(); ret = osal_copy_to_user((void __user *)arg, (void *)&ret, sizeof(int)); break; /* ---------------------------------- */ /* configure HACC HW (include SW KEY) */ /* ---------------------------------- */ case SEC_HACC_CONFIG: SMSG(bMsg,"[%s] CMD - SEC_HACC_CONFIG\n",MOD); ret = sec_boot_hacc_init(); ret = osal_copy_to_user((void __user *)arg, (void *)&ret, sizeof(int)); break; /* ---------------------------------- */ /* enable HACC HW clock */ /* ---------------------------------- */ case SEC_HACC_ENABLE_CLK: SMSG(bMsg,"[%s] CMD - SEC_HACC_ENABLE_CLK\n",MOD); ret = osal_copy_to_user((void __user *)arg, (void *)&ret, sizeof(int)); break; /* ---------------------------------- */ /* lock hacc function */ /* ---------------------------------- */ case SEC_HACC_LOCK: SMSG(bMsg,"[%s] CMD - SEC_HACC_LOCK\n",MOD); SMSG(bMsg,"[%s] lock\n",MOD); /* If the semaphore is successfully acquired, this function returns 0.*/ ret = osal_hacc_lock(); if(ret) { SMSG(true,"[%s] ERESTARTSYS\n",MOD); return -ERESTARTSYS; } return ret; /* ---------------------------------- */ /* unlock hacc function */ /* ---------------------------------- */ case SEC_HACC_UNLOCK: SMSG(bMsg,"[%s] CMD - SEC_HACC_UNLOCK\n",MOD); SMSG(bMsg,"[%s] unlock\n",MOD); osal_hacc_unlock(); break; /* ---------------------------------- */ /* check if secure boot check enabled */ /* ---------------------------------- */ case SEC_BOOT_PART_CHECK_ENABLE: SMSG(bMsg,"[%s] CMD -SEC_BOOT_PART_CHECK_ENABLE\n",MOD); if(copy_from_user((void *)part_name, (void __user *)arg, sizeof(part_name))) { return -EFAULT; } ret = sec_boot_check_part_enabled (part_name); SMSG(bMsg,"[%s] result '0x%x'\n",MOD,ret); return ret; /* ---------------------------------- */ /* notify mark incomplete */ /* ---------------------------------- */ case SEC_BOOT_NOTIFY_MARK_STATUS: SMSG(true,"[%s] mark status\n",MOD); /* may do some post process here ... */ break; /* ---------------------------------- */ /* notify check pass */ /* ---------------------------------- */ case SEC_BOOT_NOTIFY_PASS: SMSG(true,"[%s] sbchk pass\n",MOD); SMSG(true,"[%s] sbchk pass\n",MOD); SMSG(true,"[%s] sbchk pass\n",MOD); SMSG(true,"[%s] sbchk pass\n",MOD); SMSG(true,"[%s] sbchk pass\n",MOD); /* may do some post process here ... */ break; /* ---------------------------------- */ /* notify check fail */ /* ---------------------------------- */ case SEC_BOOT_NOTIFY_FAIL: if(osal_copy_from_user((void *)part_name, (void __user *)arg, sizeof(part_name))) { return -EFAULT; } SMSG(true,"[%s] sbchk fail '%s'\n",MOD,part_name); SMSG(true,"[%s] sbchk fail '%s'\n",MOD,part_name); SMSG(true,"[%s] sbchk fail '%s'\n",MOD,part_name); SMSG(true,"[%s] sbchk fail '%s'\n",MOD,part_name); SMSG(true,"[%s] sbchk fail '%s'\n",MOD,part_name); osal_msleep(3000); /* punishment ... */ SEC_ASSERT(0); break; /* ---------------------------------- */ /* notify recovery mode done */ /* ---------------------------------- */ case SEC_BOOT_NOTIFY_RMSDUP_DONE: SMSG(true,"[%s] recovery mode done\n",MOD); /* may do some post process here ... */ break; /* ---------------------------------- */ /* read rom info */ /* ---------------------------------- */ case SEC_READ_ROM_INFO: SMSG(bMsg,"[%s] read rom info\n",MOD); ret = osal_copy_to_user((void __user *)arg, (void *)&rom_info, sizeof(AND_ROMINFO_T)); break; } return 0; }
/****************************************************************************** * RETURN SECROIMG MD PLAINTEXT DATA ******************************************************************************/ uint32 sec_secro_md_get_data (SECRO_USER user, uchar* buf, uint32 offset, uint32 len) { uint32 ret = SEC_OK; const uint32 cipher_len = sizeof(AND_AC_ANDRO_T) + sizeof(AND_AC_MD_T) + sizeof(AND_AC_MD2_T); osal_secro_lock(); /* ----------------- */ /* check */ /* ----------------- */ if(FALSE == bSecroExist) { ret = ERR_SECROIMG_IS_EMPTY; goto _exit; } if(len == 0) { ret = ERR_SECROIMG_INVALID_BUF_LEN; goto _exit; } if (0 != (len % sp_hacc_blk_sz())) { ret = ERR_HACC_DATA_UNALIGNED; goto _exit; } /* ------------------------ */ /* decrypt secroimg */ /* ------------------------ */ if(TRUE == sec_secro_ac()) { sp_hacc_dec((uchar*)&secroimg.m_andro, cipher_len, TRUE,HACC_USER1,TRUE); } /* ------------------------ */ /* check header */ /* ------------------------ */ if(AC_ANDRO_MAGIC != secroimg.m_andro.magic_number) { ret = ERR_SECROIMG_HACC_AP_DECRYPT_FAIL; goto _exit; } if(AC_MD_MAGIC != secroimg.m_md.magic_number) { ret = ERR_SECROIMG_HACC_MD_DECRYPT_FAIL; goto _exit; } if(AC_MD2_MAGIC != secroimg.m_md2.magic_number) { ret = ERR_SECROIMG_HACC_MD_DECRYPT_FAIL; goto _exit; } /* ------------------------ */ /* fill buffer */ /* ------------------------ */ /* only copy the data with user specified length */ switch(user) { case SECRO_MD1: mcpy(buf,secroimg.m_md.reserve+offset,len); break; case SECRO_MD2: mcpy(buf,secroimg.m_md2.reserve+offset,len); break; default: SMSG(TRUE,"[%s] MD user not supported!\n",MOD); break; } /* ------------------------ */ /* encrypt secro image */ /* ------------------------ */ if(TRUE == sec_secro_ac()) { sp_hacc_enc((uchar*)&secroimg.m_andro, cipher_len, TRUE,HACC_USER1,TRUE); } _exit: osal_secro_unlock(); return ret; }
uint32 sec_secro_md_get_data (uchar* buf, uint32 offset, uint32 len) { uint32 ret = SEC_OK; const uint32 cipher_len = sizeof(AND_AC_ANDRO_T) + sizeof(AND_AC_MD_T); /* ----------------- */ /* check */ /* ----------------- */ if(FALSE == bSecroExist) { ret = ERR_SECROIMG_IS_EMPTY; goto _exit; } if(len == 0) { ret = ERR_SECROIMG_INVALID_BUF_LEN; goto _exit; } if (0 != (len % sp_hacc_blk_sz())) { ret = ERR_HACC_DATA_UNALIGNED; goto _exit; } /* ------------------------ */ /* decrypt secroimg */ /* ------------------------ */ if(TRUE == sec_secro_ac()) { sp_hacc_dec((uchar*)&secroimg.m_andro, cipher_len, TRUE,HACC_USER1,TRUE); } /* ------------------------ */ /* check header */ /* ------------------------ */ if(AC_ANDRO_MAGIC != secroimg.m_andro.magic_number) { ret = ERR_SECROIMG_HACC_AP_DECRYPT_FAIL; goto _exit; } if(AC_MD_MAGIC != secroimg.m_md.magic_number) { ret = ERR_SECROIMG_HACC_MD_DECRYPT_FAIL; goto _exit; } /* ------------------------ */ /* fill buffer */ /* ------------------------ */ /* only copy the data with user specified length */ mcpy(buf,secroimg.m_md.reserve+offset,len); /* ------------------------ */ /* encrypt secro image */ /* ------------------------ */ if(TRUE == sec_secro_ac()) { sp_hacc_enc((uchar*)&secroimg.m_andro, cipher_len, TRUE,HACC_USER1,TRUE); } _exit: return ret; }