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 14int 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 26int 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 42int 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 64int 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 87int 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