Home | History | Annotate | Download | only in 2lib
      1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  *
      5  * Secure storage APIs
      6  */
      7 
      8 #include "2sysincludes.h"
      9 #include "2common.h"
     10 #include "2crc8.h"
     11 #include "2misc.h"
     12 #include "2secdata.h"
     13 
     14 int vb2_secdata_check_crc(const struct vb2_context *ctx)
     15 {
     16 	const struct vb2_secdata *sec =
     17 		(const struct vb2_secdata *)ctx->secdata;
     18 
     19 	/* Verify CRC */
     20 	if (sec->crc8 != vb2_crc8(sec, offsetof(struct vb2_secdata, crc8)))
     21 		return VB2_ERROR_SECDATA_CRC;
     22 
     23 	return VB2_SUCCESS;
     24 }
     25 
     26 int vb2_secdata_create(struct vb2_context *ctx)
     27 {
     28 	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
     29 
     30 	/* Clear the entire struct */
     31 	memset(sec, 0, sizeof(*sec));
     32 
     33 	/* Set to current version */
     34 	sec->struct_version = VB2_SECDATA_VERSION;
     35 
     36 	/* Calculate initial CRC */
     37 	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
     38 	ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
     39 	return VB2_SUCCESS;
     40 }
     41 
     42 int vb2_secdata_init(struct vb2_context *ctx)
     43 {
     44 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
     45 	int rv;
     46 
     47 	rv = vb2_secdata_check_crc(ctx);
     48 	if (rv)
     49 		return rv;
     50 
     51 	/* Set status flag */
     52 	sd->status |= VB2_SD_STATUS_SECDATA_INIT;
     53 	// TODO: unit test for that
     54 
     55 	/* Read this now to make sure crossystem has it even in rec mode. */
     56 	rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS,
     57 			     &sd->fw_version_secdata);
     58 	if (rv)
     59 		return rv;
     60 
     61 	return VB2_SUCCESS;
     62 }
     63 
     64 int vb2_secdata_get(struct vb2_context *ctx,
     65 		    enum vb2_secdata_param param,
     66 		    uint32_t *dest)
     67 {
     68 	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
     69 
     70 	if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATA_INIT))
     71 		return VB2_ERROR_SECDATA_GET_UNINITIALIZED;
     72 
     73 	switch(param) {
     74 	case VB2_SECDATA_FLAGS:
     75 		*dest = sec->flags;
     76 		return VB2_SUCCESS;
     77 
     78 	case VB2_SECDATA_VERSIONS:
     79 		*dest = sec->fw_versions;
     80 		return VB2_SUCCESS;
     81 
     82 	default:
     83 		return VB2_ERROR_SECDATA_GET_PARAM;
     84 	}
     85 }
     86 
     87 int vb2_secdata_set(struct vb2_context *ctx,
     88 		    enum vb2_secdata_param param,
     89 		    uint32_t value)
     90 {
     91 	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
     92 	uint32_t now;
     93 
     94 	if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATA_INIT))
     95 		return VB2_ERROR_SECDATA_SET_UNINITIALIZED;
     96 
     97 	/* If not changing the value, don't regenerate the CRC. */
     98 	if (vb2_secdata_get(ctx, param, &now) == VB2_SUCCESS && now == value)
     99 		return VB2_SUCCESS;
    100 
    101 	switch(param) {
    102 	case VB2_SECDATA_FLAGS:
    103 		/* Make sure flags is in valid range */
    104 		if (value > 0xff)
    105 			return VB2_ERROR_SECDATA_SET_FLAGS;
    106 
    107 		sec->flags = value;
    108 		break;
    109 
    110 	case VB2_SECDATA_VERSIONS:
    111 		sec->fw_versions = value;
    112 		break;
    113 
    114 	default:
    115 		return VB2_ERROR_SECDATA_SET_PARAM;
    116 	}
    117 
    118 	/* Regenerate CRC */
    119 	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
    120 	ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
    121 	return VB2_SUCCESS;
    122 }
    123