diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2013-03-19 14:14:30 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2013-03-19 14:14:30 -0700 |
commit | 729ac021a035432dea68ddfdb6ea2fb1b6ed4f23 (patch) | |
tree | 66feb5294d01163e382bab115072f4615e64d46a | |
parent | 48a96c77d031520690372387ed391faf2b8e019d (diff) | |
parent | 6173b87a9dde4dc65f00ea8b5f37f5418a1d18fe (diff) | |
download | lk-729ac021a035432dea68ddfdb6ea2fb1b6ed4f23.tar.gz |
Merge "msm_shared: Update to ssd feature"
-rw-r--r-- | platform/msm_shared/include/scm.h | 2 | ||||
-rw-r--r-- | platform/msm_shared/scm.c | 118 |
2 files changed, 77 insertions, 43 deletions
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h index 0442c023..a565b2fb 100644 --- a/platform/msm_shared/include/scm.h +++ b/platform/msm_shared/include/scm.h @@ -36,6 +36,8 @@ #define ENCRYPT_MAGIC_1 0x676D6973 #define SSD_HEADER_MAGIC_SIZE 8 #define SSD_HEADER_XML_SIZE 2048 +#define SSD_HEADER_MIN_SIZE 128 +#define MULTIPLICATION_FACTOR 2 typedef unsigned int uint32; diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c index afdd005f..d33d14e4 100644 --- a/platform/msm_shared/scm.c +++ b/platform/msm_shared/scm.c @@ -261,22 +261,47 @@ int decrypt_scm(uint32_t ** img_ptr, uint32_t * img_len_ptr) static int ssd_image_is_encrypted(uint32_t ** img_ptr, uint32_t * img_len_ptr, uint32 * ctx_id) { - int ret = 0; + int ret = 0; ssd_parse_md_req parse_req; ssd_parse_md_rsp parse_rsp; + int prev_len = 0; + + /* Populate meta-data ptr. Here md_len is the meta-data length. + * The Code below follows a growing length approach. First send + * min(img_len_ptr,SSD_HEADER_MIN_SIZE) say 128 bytes for example. + * If parse_rsp.status = PARSING_INCOMPLETE we send md_len = 256. + * If subsequent status = PARSING_INCOMPLETE we send md_len = 512, + * 1024bytes and so on until we get an valid response(rsp.status) from TZ*/ - /* populate meta-data ptr */ parse_req.md = (uint32*)*img_ptr; - parse_req.md_len = (uint32)*img_len_ptr; + parse_req.md_len = ((*img_len_ptr) >= SSD_HEADER_MIN_SIZE) ? SSD_HEADER_MIN_SIZE : (*img_len_ptr); - arch_clean_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr); + arch_clean_invalidate_cache_range((addr_t) *img_ptr, parse_req.md_len); - ret = scm_call(SCM_SVC_SSD, - SSD_PARSE_MD_ID, - &parse_req, - sizeof(parse_req), - &parse_rsp, - sizeof(parse_rsp)); + do + { + ret = scm_call(SCM_SVC_SSD, + SSD_PARSE_MD_ID, + &parse_req, + sizeof(parse_req), + &parse_rsp, + sizeof(parse_rsp)); + + if(!ret && (parse_rsp.status == SSD_PMD_PARSING_INCOMPLETE)) + { + prev_len = parse_req.md_len; + + parse_req.md_len *= MULTIPLICATION_FACTOR; + + arch_clean_invalidate_cache_range((addr_t) *(img_ptr + prev_len), + (parse_req.md_len - prev_len) ); + + continue; + } + else + break; + + } while(true); if(!ret) { @@ -292,6 +317,12 @@ static int ssd_image_is_encrypted(uint32_t ** img_ptr, uint32_t * img_len_ptr, u dprintf(INFO,"Image is not encrypted"); } } + else + { + dprintf(CRITICAL,"ssd_image_is_encrypted call failed"); + + ASSERT(ret == 0); + } return ret; } @@ -303,42 +334,43 @@ int decrypt_scm_v2(uint32_t ** img_ptr, uint32_t * img_len_ptr) ssd_decrypt_img_frag_req decrypt_req; ssd_decrypt_img_frag_rsp decrypt_rsp; - /* Image data is operated upon by TZ, which accesses only the main memory. - * It must be flushed/invalidated before and after TZ call. - */ - arch_clean_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr); - if(ssd_image_is_encrypted(img_ptr,img_len_ptr,&ctx_id)) - { - /*decrypt the image here*/ - - decrypt_req.md_ctx_id = ctx_id; - decrypt_req.last_frag = 1; - decrypt_req.frag_len = *img_len_ptr; - decrypt_req.frag = *img_ptr; - - ret = scm_call(SCM_SVC_SSD, - SSD_DECRYPT_IMG_FRAG_ID, - &decrypt_req, - sizeof(decrypt_req), - &decrypt_rsp, - sizeof(decrypt_rsp)); - - if(!ret) - { - ret = decrypt_rsp.status; - } - - /* Values at img_ptr and img_len_ptr are updated by TZ. Must be invalidated - * before we use them. - */ - arch_invalidate_cache_range((addr_t) img_ptr, sizeof(img_ptr)); - arch_invalidate_cache_range((addr_t) img_len_ptr, sizeof(img_len_ptr)); - - /* Invalidate the updated image data */ - arch_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr); + { + + /* Image data is operated upon by TZ, which accesses only the main memory. + * It must be flushed/invalidated before and after TZ call. + */ + + arch_clean_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr); + + /*decrypt the image here*/ + + decrypt_req.md_ctx_id = ctx_id; + decrypt_req.last_frag = 1; + decrypt_req.frag_len = *img_len_ptr; + decrypt_req.frag = *img_ptr; + + ret = scm_call(SCM_SVC_SSD, + SSD_DECRYPT_IMG_FRAG_ID, + &decrypt_req, + sizeof(decrypt_req), + &decrypt_rsp, + sizeof(decrypt_rsp)); + + if(!ret){ + ret = decrypt_rsp.status; } + /* Values at img_ptr and img_len_ptr are updated by TZ. Must be invalidated + * before we use them. + */ + arch_invalidate_cache_range((addr_t) img_ptr, sizeof(img_ptr)); + arch_invalidate_cache_range((addr_t) img_len_ptr, sizeof(img_len_ptr)); + + /* Invalidate the updated image data */ + arch_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr); + } + return ret; } |