2secdata.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. #include "2sysincludes.h"
  8. #include "2common.h"
  9. #include "2crc8.h"
  10. #include "2misc.h"
  11. #include "2secdata.h"
  12. int vb2_secdata_check_crc(const struct vb2_context *ctx)
  13. {
  14. const struct vb2_secdata *sec =
  15. (const struct vb2_secdata *)ctx->secdata;
  16. /* Verify CRC */
  17. if (sec->crc8 != vb2_crc8(sec, offsetof(struct vb2_secdata, crc8)))
  18. return VB2_ERROR_SECDATA_CRC;
  19. /* CRC(<000...00>) is 0, so check version as well (should never be 0) */
  20. if (!sec->struct_version)
  21. return VB2_ERROR_SECDATA_ZERO;
  22. return VB2_SUCCESS;
  23. }
  24. int vb2_secdata_create(struct vb2_context *ctx)
  25. {
  26. struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
  27. /* Clear the entire struct */
  28. memset(sec, 0, sizeof(*sec));
  29. /* Set to current version */
  30. sec->struct_version = VB2_SECDATA_VERSION;
  31. /* Calculate initial CRC */
  32. sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
  33. ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
  34. return VB2_SUCCESS;
  35. }
  36. int vb2_secdata_init(struct vb2_context *ctx)
  37. {
  38. struct vb2_shared_data *sd = vb2_get_sd(ctx);
  39. int rv;
  40. rv = vb2_secdata_check_crc(ctx);
  41. if (rv)
  42. return rv;
  43. /* Set status flag */
  44. sd->status |= VB2_SD_STATUS_SECDATA_INIT;
  45. /* TODO: unit test for that */
  46. /* Read this now to make sure crossystem has it even in rec mode. */
  47. rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS,
  48. &sd->fw_version_secdata);
  49. if (rv)
  50. return rv;
  51. return VB2_SUCCESS;
  52. }
  53. int vb2_secdata_get(struct vb2_context *ctx,
  54. enum vb2_secdata_param param,
  55. uint32_t *dest)
  56. {
  57. struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
  58. if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATA_INIT))
  59. return VB2_ERROR_SECDATA_GET_UNINITIALIZED;
  60. switch(param) {
  61. case VB2_SECDATA_FLAGS:
  62. *dest = sec->flags;
  63. return VB2_SUCCESS;
  64. case VB2_SECDATA_VERSIONS:
  65. *dest = sec->fw_versions;
  66. return VB2_SUCCESS;
  67. default:
  68. return VB2_ERROR_SECDATA_GET_PARAM;
  69. }
  70. }
  71. int vb2_secdata_set(struct vb2_context *ctx,
  72. enum vb2_secdata_param param,
  73. uint32_t value)
  74. {
  75. struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
  76. uint32_t now;
  77. if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATA_INIT))
  78. return VB2_ERROR_SECDATA_SET_UNINITIALIZED;
  79. /* If not changing the value, don't regenerate the CRC. */
  80. if (vb2_secdata_get(ctx, param, &now) == VB2_SUCCESS && now == value)
  81. return VB2_SUCCESS;
  82. switch(param) {
  83. case VB2_SECDATA_FLAGS:
  84. /* Make sure flags is in valid range */
  85. if (value > 0xff)
  86. return VB2_ERROR_SECDATA_SET_FLAGS;
  87. sec->flags = value;
  88. break;
  89. case VB2_SECDATA_VERSIONS:
  90. sec->fw_versions = value;
  91. break;
  92. default:
  93. return VB2_ERROR_SECDATA_SET_PARAM;
  94. }
  95. /* Regenerate CRC */
  96. sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
  97. ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
  98. return VB2_SUCCESS;
  99. }