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 * Misc functions which need access to vb2_context but are not public APIs
66f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler */
76f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
86f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2sysincludes.h"
96f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2api.h"
106f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2misc.h"
116f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2nvstorage.h"
126f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2secdata.h"
136f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2sha.h"
146f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "2rsa.h"
156f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler#include "vb2_common.h"
166f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
176f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spanglerint vb2_load_fw_keyblock(struct vb2_context *ctx)
186f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler{
196f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_shared_data *sd = vb2_get_sd(ctx);
206f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_workbuf wb;
216f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
226f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	uint8_t *key_data;
236f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	uint32_t key_size;
246f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_packed_key *packed_key;
256f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_public_key root_key;
266f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
276f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_keyblock *kb;
286f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	uint32_t block_size;
296f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
306f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	int rv;
316f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
326f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	vb2_workbuf_from_ctx(ctx, &wb);
336f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
346f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Read the root key */
356f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	key_size = sd->gbb_rootkey_size;
366f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	key_data = vb2_workbuf_alloc(&wb, key_size);
376f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (!key_data)
386f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;
396f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
406f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2ex_read_resource(ctx, VB2_RES_GBB, sd->gbb_rootkey_offset,
416f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler				 key_data, key_size);
426f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
436f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
446f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
456f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Unpack the root key */
466f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2_unpack_key(&root_key, key_data, key_size);
476f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
486f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
496f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
506f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Load the firmware keyblock header after the root key */
516f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
526f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (!kb)
536f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER;
546f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
556f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, sizeof(*kb));
566f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
576f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
586f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
596f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	block_size = kb->keyblock_size;
606f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
616f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/*
626f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * Load the entire keyblock, now that we know how big it is.  Note that
636f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * we're loading the entire keyblock instead of just the piece after
646f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * the header.  That means we re-read the header.  But that's a tiny
656f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * amount of data, and it makes the code much more straightforward.
666f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 */
676f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	kb = vb2_workbuf_realloc(&wb, sizeof(*kb), block_size);
686f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (!kb)
696f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return VB2_ERROR_FW_KEYBLOCK_WORKBUF;
706f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
716f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size);
726f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
736f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
746f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
756f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Verify the keyblock */
766f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2_verify_keyblock(kb, block_size, &root_key, &wb);
77187f069f8999d879193d380f374a890c114ad98dJulius Werner	if (rv) {
78187f069f8999d879193d380f374a890c114ad98dJulius Werner		vb2_fail(ctx, VB2_RECOVERY_FW_KEYBLOCK, rv);
796f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
80187f069f8999d879193d380f374a890c114ad98dJulius Werner	}
816f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
826f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Key version is the upper 16 bits of the composite firmware version */
836f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (kb->data_key.key_version > 0xffff)
84187f069f8999d879193d380f374a890c114ad98dJulius Werner		rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
85187f069f8999d879193d380f374a890c114ad98dJulius Werner	if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16))
86187f069f8999d879193d380f374a890c114ad98dJulius Werner		rv = VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
87187f069f8999d879193d380f374a890c114ad98dJulius Werner	if (rv) {
88187f069f8999d879193d380f374a890c114ad98dJulius Werner		vb2_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
89187f069f8999d879193d380f374a890c114ad98dJulius Werner		return rv;
90187f069f8999d879193d380f374a890c114ad98dJulius Werner	}
916f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
926f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->fw_version = kb->data_key.key_version << 16;
936f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
946f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/*
956f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * Save the data key in the work buffer.  This overwrites the root key
966f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * we read above.  That's ok, because now that we have the data key we
976f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * no longer need the root key.
986f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 */
996f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	packed_key = (struct vb2_packed_key *)key_data;
1006f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1016f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	packed_key->algorithm = kb->data_key.algorithm;
1026f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	packed_key->key_version = kb->data_key.key_version;
1036f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	packed_key->key_size = kb->data_key.key_size;
1046f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1056f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/*
1066f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * Use memmove() instead of memcpy().  In theory, the destination will
1076f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * never overlap because with the source because the root key is likely
1086f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * to be at least as large as the data key, but there's no harm here in
1096f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * being paranoid.
1106f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 */
1116f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	memmove(key_data + packed_key->key_offset,
1126f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		(uint8_t*)&kb->data_key + kb->data_key.key_offset,
1136f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		packed_key->key_size);
1146f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1156f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Save the packed key offset and size */
1166f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->workbuf_data_key_offset = vb2_offset_of(ctx->workbuf, key_data);
1176f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->workbuf_data_key_size =
1186f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		packed_key->key_offset + packed_key->key_size;
1196f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1206f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Preamble follows the keyblock in the vblock */
1216f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->vblock_preamble_offset = kb->keyblock_size;
1226f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1236f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Data key will persist in the workbuf after we return */
1246f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	ctx->workbuf_used = sd->workbuf_data_key_offset +
1256f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		sd->workbuf_data_key_size;
1266f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1276f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	return VB2_SUCCESS;
1286f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler}
1296f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1306f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spanglerint vb2_load_fw_preamble(struct vb2_context *ctx)
1316f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler{
1326f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_shared_data *sd = vb2_get_sd(ctx);
1336f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_workbuf wb;
1346f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1356f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	uint8_t *key_data = ctx->workbuf + sd->workbuf_data_key_offset;
1366f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	uint32_t key_size = sd->workbuf_data_key_size;
1376f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_public_key data_key;
1386f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1396f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Preamble goes in the next unused chunk of work buffer */
1406f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	struct vb2_fw_preamble *pre;
1416f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	uint32_t pre_size;
1426f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1436f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	int rv;
1446f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1456f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	vb2_workbuf_from_ctx(ctx, &wb);
1466f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1476f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Unpack the firmware data key */
1486f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (!sd->workbuf_data_key_size)
1496f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;
1506f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1516f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2_unpack_key(&data_key, key_data, key_size);
1526f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
1536f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
1546f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1556f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Load the firmware preamble header */
1566f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
1576f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (!pre)
1586f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER;
1596f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1606f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
1616f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler				 sd->vblock_preamble_offset,
1626f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler				 pre, sizeof(*pre));
1636f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
1646f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
1656f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1666f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	pre_size = pre->preamble_size;
1676f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1686f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Load the entire firmware preamble, now that we know how big it is */
1696f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	pre = vb2_workbuf_realloc(&wb, sizeof(*pre), pre_size);
1706f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (!pre)
1716f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return VB2_ERROR_FW_PREAMBLE2_WORKBUF;
1726f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1736f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
1746f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler				 sd->vblock_preamble_offset,
1756f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler				 pre, pre_size);
1766f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (rv)
1776f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
1786f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1796f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Work buffer now contains the data subkey data and the preamble */
1806f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1816f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Verify the preamble */
1826f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	rv = vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb);
183187f069f8999d879193d380f374a890c114ad98dJulius Werner	if (rv) {
184187f069f8999d879193d380f374a890c114ad98dJulius Werner		vb2_fail(ctx, VB2_RECOVERY_FW_PREAMBLE, rv);
1856f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		return rv;
186187f069f8999d879193d380f374a890c114ad98dJulius Werner	}
1876f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
1886f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/*
1896f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * Firmware version is the lower 16 bits of the composite firmware
1906f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * version.
1916f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 */
1926f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	if (pre->firmware_version > 0xffff)
193187f069f8999d879193d380f374a890c114ad98dJulius Werner		rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
1946f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Combine with the key version from vb2_load_fw_keyblock() */
1956f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->fw_version |= pre->firmware_version;
196187f069f8999d879193d380f374a890c114ad98dJulius Werner	if (!rv && sd->fw_version < sd->fw_version_secdata)
197187f069f8999d879193d380f374a890c114ad98dJulius Werner		rv = VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
198187f069f8999d879193d380f374a890c114ad98dJulius Werner	if (rv) {
199187f069f8999d879193d380f374a890c114ad98dJulius Werner		vb2_fail(ctx, VB2_RECOVERY_FW_ROLLBACK, rv);
200187f069f8999d879193d380f374a890c114ad98dJulius Werner		return rv;
201187f069f8999d879193d380f374a890c114ad98dJulius Werner	}
2026f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
2036f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/*
2046f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * If this is a newer version than in secure storage, and we
2056f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * successfully booted the same slot last boot, roll forward the
2066f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 * version in secure storage.
2076f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	 */
20821aedee1ceab57dcbe8506d10a132dffd3a1917bJulius Werner	if (sd->fw_version > sd->fw_version_secdata &&
2096f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	    sd->last_fw_slot == sd->fw_slot &&
2106f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	    sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
2116f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
21221aedee1ceab57dcbe8506d10a132dffd3a1917bJulius Werner		sd->fw_version_secdata = sd->fw_version;
2136f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version);
2146f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler		if (rv)
2156f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler			return rv;
2166f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	}
2176f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
2186f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Keep track of where we put the preamble */
2196f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->workbuf_preamble_offset = vb2_offset_of(ctx->workbuf, pre);
2206f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	sd->workbuf_preamble_size = pre_size;
2216f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
2226f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	/* Preamble will persist in work buffer after we return */
2236f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	ctx->workbuf_used = sd->workbuf_preamble_offset + pre_size;
2246f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler
2256f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler	return VB2_SUCCESS;
2266f1b82ac14f341d9733d6e95d518b3ee352002efRandall Spangler}
227