16f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 26f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * Use of this source code is governed by a BSD-style license that can be 36f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * found in the LICENSE file. 46f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * 56f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * Externally-callable APIs 66f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * (Firmware portion) 76f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler */ 86f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 96f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2sysincludes.h" 106f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2api.h" 116f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2misc.h" 126f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2nvstorage.h" 136f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2secdata.h" 146f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2sha.h" 156f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2rsa.h" 166f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "vb2_common.h" 176f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 186f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spanglerint vb2api_fw_phase3(struct vb2_context *ctx) 196f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler{ 206f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler int rv; 216f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 226f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Verify firmware keyblock */ 236f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler rv = vb2_load_fw_keyblock(ctx); 246f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (rv) { 256f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); 266f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return rv; 276f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler } 286f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 296f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Verify firmware preamble */ 306f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler rv = vb2_load_fw_preamble(ctx); 316f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (rv) { 326f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); 336f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return rv; 346f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler } 356f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 366f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_SUCCESS; 376f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler} 386f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 396f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spanglerint vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, uint32_t *size) 406f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler{ 416f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_shared_data *sd = vb2_get_sd(ctx); 426f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler const struct vb2_fw_preamble *pre; 436f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_digest_context *dc; 446f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_public_key key; 456f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_workbuf wb; 466f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler int rv; 476f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 486f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler vb2_workbuf_from_ctx(ctx, &wb); 496f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 506f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (tag == VB2_HASH_TAG_INVALID) 516f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_INIT_HASH_TAG; 526f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 536f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Get preamble pointer */ 546f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!sd->workbuf_preamble_size) 556f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_INIT_HASH_PREAMBLE; 566f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler pre = (const struct vb2_fw_preamble *) 576f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler (ctx->workbuf + sd->workbuf_preamble_offset); 586f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 596f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* For now, we only support the firmware body tag */ 606f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (tag != VB2_HASH_TAG_FW_BODY) 616f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_INIT_HASH_TAG; 626f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 636f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Allocate workbuf space for the hash */ 646f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (sd->workbuf_hash_size) { 656f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler dc = (struct vb2_digest_context *) 666f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler (ctx->workbuf + sd->workbuf_hash_offset); 676f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler } else { 686f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler uint32_t dig_size = sizeof(*dc); 696f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 706f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler dc = vb2_workbuf_alloc(&wb, dig_size); 716f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!dc) 726f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_INIT_HASH_WORKBUF; 736f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 746f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler sd->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc); 756f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler sd->workbuf_hash_size = dig_size; 766f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler ctx->workbuf_used = sd->workbuf_hash_offset + dig_size; 776f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler } 786f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 796f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* 806f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * Unpack the firmware data key to see which hashing algorithm we 816f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * should use. 826f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * 836f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * TODO: really, the firmware body should be hashed, and not signed, 846f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * because the signature we're checking is already signed as part of 856f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * the firmware preamble. But until we can change the signing scripts, 866f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * we're stuck with a signature here instead of a hash. 876f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler */ 886f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!sd->workbuf_data_key_size) 896f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_INIT_HASH_DATA_KEY; 906f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 916f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler rv = vb2_unpack_key(&key, 926f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler ctx->workbuf + sd->workbuf_data_key_offset, 936f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler sd->workbuf_data_key_size); 946f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (rv) 956f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return rv; 966f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 976f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler sd->hash_tag = tag; 986f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler sd->hash_remaining_size = pre->body_signature.data_size; 996f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1006f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (size) 1016f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler *size = pre->body_signature.data_size; 1026f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 103f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) { 104f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner rv = vb2ex_hwcrypto_digest_init(key.hash_alg, 105f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner pre->body_signature.data_size); 106f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (!rv) { 107f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner VB2_DEBUG("Using HW crypto engine for hash_alg %d\n", 108f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner key.hash_alg); 109f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner dc->hash_alg = key.hash_alg; 110f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner dc->using_hwcrypto = 1; 111f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner return VB2_SUCCESS; 112f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner } 113f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) 114f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner return rv; 115f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n", 116f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner key.hash_alg); 117f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner } else { 118f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner VB2_DEBUG("HW crypto forbidden by preamble, using SW\n"); 119f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner } 120f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner 1216f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return vb2_digest_init(dc, key.hash_alg); 1226f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler} 1236f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1246f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spanglerint vb2api_check_hash(struct vb2_context *ctx) 1256f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler{ 1266f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_shared_data *sd = vb2_get_sd(ctx); 1276f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_digest_context *dc = (struct vb2_digest_context *) 1286f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler (ctx->workbuf + sd->workbuf_hash_offset); 1296f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_workbuf wb; 1306f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1316f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler uint8_t *digest; 1326f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler uint32_t digest_size = vb2_digest_size(dc->hash_alg); 1336f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1346f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_fw_preamble *pre; 1356f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler struct vb2_public_key key; 1366f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler int rv; 1376f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1386f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler vb2_workbuf_from_ctx(ctx, &wb); 1396f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1406f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Get preamble pointer */ 1416f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!sd->workbuf_preamble_size) 1426f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_CHECK_HASH_PREAMBLE; 1436f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler pre = (struct vb2_fw_preamble *) 1446f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler (ctx->workbuf + sd->workbuf_preamble_offset); 1456f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1466f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Must have initialized hash digest work area */ 1476f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!sd->workbuf_hash_size) 1486f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_CHECK_HASH_WORKBUF; 1496f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1506f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Should have hashed the right amount of data */ 1516f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (sd->hash_remaining_size) 1526f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_CHECK_HASH_SIZE; 1536f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1546f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Allocate the digest */ 1556f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler digest = vb2_workbuf_alloc(&wb, digest_size); 1566f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!digest) 1576f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; 1586f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1596f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Finalize the digest */ 160f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (dc->using_hwcrypto) 161f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size); 162f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner else 163f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner rv = vb2_digest_finalize(dc, digest, digest_size); 1646f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (rv) 1656f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return rv; 1666f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1676f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* The code below is specific to the body signature */ 1686f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (sd->hash_tag != VB2_HASH_TAG_FW_BODY) 1696f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_CHECK_HASH_TAG; 1706f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1716f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* 1726f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * The body signature is currently a *signature* of the body data, not 1736f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * just its hash. So we need to verify the signature. 1746f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler */ 1756f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1766f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* Unpack the data key */ 1776f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (!sd->workbuf_data_key_size) 1786f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return VB2_ERROR_API_CHECK_HASH_DATA_KEY; 1796f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1806f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler rv = vb2_unpack_key(&key, 1816f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler ctx->workbuf + sd->workbuf_data_key_offset, 1826f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler sd->workbuf_data_key_size); 1836f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (rv) 1846f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return rv; 1856f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1866f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler /* 1876f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * Check digest vs. signature. Note that this destroys the signature. 1886f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler * That's ok, because we only check each signature once per boot. 1896f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler */ 1906f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb); 1916f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler if (rv) 192187f069f8999d879193d380f374a890c114ad98dJulius Werner vb2_fail(ctx, VB2_RECOVERY_FW_BODY, rv); 1936f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler 1946f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler return rv; 1956f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler} 196