mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 13:55:56 +00:00
Merge "fix(driver/auth): avoid NV counter upgrade without certificate validation" into integration
This commit is contained in:
commit
2ba56793d1
1 changed files with 34 additions and 13 deletions
|
@ -222,19 +222,25 @@ static int auth_signature(const auth_method_param_sig_t *param,
|
||||||
* To protect the system against rollback, the platform includes a non-volatile
|
* To protect the system against rollback, the platform includes a non-volatile
|
||||||
* counter whose value can only be increased. All certificates include a counter
|
* counter whose value can only be increased. All certificates include a counter
|
||||||
* value that should not be lower than the value stored in the platform. If the
|
* value that should not be lower than the value stored in the platform. If the
|
||||||
* value is larger, the counter in the platform must be updated to the new
|
* value is larger, the counter in the platform must be updated to the new value
|
||||||
* value.
|
* (provided it has been authenticated).
|
||||||
*
|
*
|
||||||
* Return: 0 = success, Otherwise = error
|
* Return: 0 = success, Otherwise = error
|
||||||
|
* Returns additionally,
|
||||||
|
* cert_nv_ctr -> NV counter value present in the certificate
|
||||||
|
* need_nv_ctr_upgrade = 0 -> platform NV counter upgrade is not needed
|
||||||
|
* need_nv_ctr_upgrade = 1 -> platform NV counter upgrade is needed
|
||||||
*/
|
*/
|
||||||
static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
|
static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
|
||||||
const auth_img_desc_t *img_desc,
|
const auth_img_desc_t *img_desc,
|
||||||
void *img, unsigned int img_len)
|
void *img, unsigned int img_len,
|
||||||
|
unsigned int *cert_nv_ctr,
|
||||||
|
bool *need_nv_ctr_upgrade)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
void *data_ptr = NULL;
|
void *data_ptr = NULL;
|
||||||
unsigned int data_len, len, i;
|
unsigned int data_len, len, i;
|
||||||
unsigned int cert_nv_ctr, plat_nv_ctr;
|
unsigned int plat_nv_ctr;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* Get the counter value from current image. The AM expects the IPM
|
/* Get the counter value from current image. The AM expects the IPM
|
||||||
|
@ -265,22 +271,20 @@ static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to unsigned int. This code is for a little-endian CPU */
|
/* Convert to unsigned int. This code is for a little-endian CPU */
|
||||||
cert_nv_ctr = 0;
|
*cert_nv_ctr = 0;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
cert_nv_ctr = (cert_nv_ctr << 8) | *p++;
|
*cert_nv_ctr = (*cert_nv_ctr << 8) | *p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the counter from the platform */
|
/* Get the counter from the platform */
|
||||||
rc = plat_get_nv_ctr(param->plat_nv_ctr->cookie, &plat_nv_ctr);
|
rc = plat_get_nv_ctr(param->plat_nv_ctr->cookie, &plat_nv_ctr);
|
||||||
return_if_error(rc);
|
return_if_error(rc);
|
||||||
|
|
||||||
if (cert_nv_ctr < plat_nv_ctr) {
|
if (*cert_nv_ctr < plat_nv_ctr) {
|
||||||
/* Invalid NV-counter */
|
/* Invalid NV-counter */
|
||||||
return 1;
|
return 1;
|
||||||
} else if (cert_nv_ctr > plat_nv_ctr) {
|
} else if (*cert_nv_ctr > plat_nv_ctr) {
|
||||||
rc = plat_set_nv_ctr2(param->plat_nv_ctr->cookie,
|
*need_nv_ctr_upgrade = true;
|
||||||
img_desc, cert_nv_ctr);
|
|
||||||
return_if_error(rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -351,6 +355,10 @@ int auth_mod_verify_img(unsigned int img_id,
|
||||||
void *param_ptr;
|
void *param_ptr;
|
||||||
unsigned int param_len;
|
unsigned int param_len;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
unsigned int cert_nv_ctr = 0;
|
||||||
|
bool need_nv_ctr_upgrade = false;
|
||||||
|
bool sig_auth_done = false;
|
||||||
|
const auth_method_param_nv_ctr_t *nv_ctr_param = NULL;
|
||||||
|
|
||||||
/* Get the image descriptor from the chain of trust */
|
/* Get the image descriptor from the chain of trust */
|
||||||
img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
|
img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
|
||||||
|
@ -376,10 +384,13 @@ int auth_mod_verify_img(unsigned int img_id,
|
||||||
case AUTH_METHOD_SIG:
|
case AUTH_METHOD_SIG:
|
||||||
rc = auth_signature(&auth_method->param.sig,
|
rc = auth_signature(&auth_method->param.sig,
|
||||||
img_desc, img_ptr, img_len);
|
img_desc, img_ptr, img_len);
|
||||||
|
sig_auth_done = true;
|
||||||
break;
|
break;
|
||||||
case AUTH_METHOD_NV_CTR:
|
case AUTH_METHOD_NV_CTR:
|
||||||
rc = auth_nvctr(&auth_method->param.nv_ctr,
|
nv_ctr_param = &auth_method->param.nv_ctr;
|
||||||
img_desc, img_ptr, img_len);
|
rc = auth_nvctr(nv_ctr_param,
|
||||||
|
img_desc, img_ptr, img_len,
|
||||||
|
&cert_nv_ctr, &need_nv_ctr_upgrade);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unknown authentication method */
|
/* Unknown authentication method */
|
||||||
|
@ -389,6 +400,16 @@ int auth_mod_verify_img(unsigned int img_id,
|
||||||
return_if_error(rc);
|
return_if_error(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do platform NV counter upgrade only if the certificate gets
|
||||||
|
* authenticated, and platform NV-counter upgrade is needed.
|
||||||
|
*/
|
||||||
|
if (need_nv_ctr_upgrade && sig_auth_done) {
|
||||||
|
rc = plat_set_nv_ctr2(nv_ctr_param->plat_nv_ctr->cookie,
|
||||||
|
img_desc, cert_nv_ctr);
|
||||||
|
return_if_error(rc);
|
||||||
|
}
|
||||||
|
|
||||||
/* Extract the parameters indicated in the image descriptor to
|
/* Extract the parameters indicated in the image descriptor to
|
||||||
* authenticate the children images. */
|
* authenticate the children images. */
|
||||||
if (img_desc->authenticated_data != NULL) {
|
if (img_desc->authenticated_data != NULL) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue