|  | /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | * | 
|  | * Common functions between firmware and kernel verified boot. | 
|  | */ | 
|  |  | 
|  | #pragma once | 
|  |  | 
|  | #include "2api.h" | 
|  | #include "2return_codes.h" | 
|  | #include "2sha.h" | 
|  | #include "2struct.h" | 
|  |  | 
|  | struct vb2_public_key; | 
|  |  | 
|  | /* | 
|  | * Return the greater of A and B.  This is used in macros which calculate the | 
|  | * required buffer size, so can't be turned into a static inline function. | 
|  | */ | 
|  | #ifndef VB2_MAX | 
|  | #define VB2_MAX(A, B) ((A) > (B) ? (A) : (B)) | 
|  | #endif | 
|  |  | 
|  | /* Return the number of elements in an array */ | 
|  | #ifndef ARRAY_SIZE | 
|  | #define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) | 
|  | #endif | 
|  |  | 
|  | /* Debug output printf() for tests.  Otherwise, it's platform-dependent. */ | 
|  | #if defined(VBOOT_DEBUG) | 
|  | #  if defined(FOR_TEST) | 
|  | #    define VB2_DEBUG(format, args...) printf(format, ## args) | 
|  | #  else | 
|  | #    define VB2_DEBUG(format, args...) vb2ex_printf(__func__, format, ## args) | 
|  | #  endif | 
|  | #else | 
|  | #  define VB2_DEBUG(format, args...) | 
|  | #endif | 
|  |  | 
|  | /* | 
|  | * Alignment for work buffer pointers/allocations should be useful for any | 
|  | * data type. When declaring workbuf buffers on the stack, the caller should | 
|  | * use explicit alignment to avoid run-time errors. For example: | 
|  | * | 
|  | *    int foo(void) | 
|  | *    { | 
|  | *        struct vb2_workbuf wb; | 
|  | *        uint8_t buf[NUM] __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); | 
|  | *        wb.buf = buf; | 
|  | *        wb.size = sizeof(buf); | 
|  | */ | 
|  |  | 
|  | /* We might get away with using __alignof__(void *), but since GCC defines a | 
|  | * macro for us we'll be safe and use that. */ | 
|  | #define VB2_WORKBUF_ALIGN __BIGGEST_ALIGNMENT__ | 
|  |  | 
|  | /* Work buffer */ | 
|  | struct vb2_workbuf { | 
|  | uint8_t *buf; | 
|  | uint32_t size; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Initialize a work buffer. | 
|  | * | 
|  | * @param wb		Work buffer to init | 
|  | * @param buf		Pointer to work buffer data | 
|  | * @param size		Size of work buffer data in bytes | 
|  | */ | 
|  | void vb2_workbuf_init(struct vb2_workbuf *wb, uint8_t *buf, uint32_t size); | 
|  |  | 
|  | /** | 
|  | * Allocate space in a work buffer. | 
|  | * | 
|  | * Note that the returned buffer will always be aligned to VB2_WORKBUF_ALIGN. | 
|  | * | 
|  | * The work buffer acts like a stack, and detailed tracking of allocs and frees | 
|  | * is not done.  The caller must track the size of each allocation and free via | 
|  | * vb2_workbuf_free() in the reverse order they were allocated. | 
|  | * | 
|  | * An acceptable alternate workflow inside a function is to pass in a const | 
|  | * work buffer, then make a local copy.  Allocations done to the local copy | 
|  | * then don't change the passed-in work buffer, and will effectively be freed | 
|  | * when the local copy goes out of scope. | 
|  | * | 
|  | * @param wb		Work buffer | 
|  | * @param size		Requested size in bytes | 
|  | * @return A pointer to the allocated space, or NULL if error. | 
|  | */ | 
|  | void *vb2_workbuf_alloc(struct vb2_workbuf *wb, uint32_t size); | 
|  |  | 
|  | /** | 
|  | * Reallocate space in a work buffer. | 
|  | * | 
|  | * Note that the returned buffer will always be aligned to VB2_WORKBUF_ALIGN. | 
|  | * The work buffer acts like a stack, so this must only be done to the most | 
|  | * recently allocated buffer. | 
|  | * | 
|  | * @param wb		Work buffer | 
|  | * @param oldsize	Old allocation size in bytes | 
|  | * @param newsize	Requested size in bytes | 
|  | * @return A pointer to the allocated space, or NULL if error. | 
|  | */ | 
|  | void *vb2_workbuf_realloc(struct vb2_workbuf *wb, | 
|  | uint32_t oldsize, | 
|  | uint32_t newsize); | 
|  |  | 
|  | /** | 
|  | * Free the preceding allocation. | 
|  | * | 
|  | * Note that the work buffer acts like a stack, and detailed tracking of | 
|  | * allocs and frees is not done.  The caller must track the size of each | 
|  | * allocation and free them in reverse order. | 
|  | * | 
|  | * @param wb		Work buffer | 
|  | * @param size		Size of data to free | 
|  | */ | 
|  | void vb2_workbuf_free(struct vb2_workbuf *wb, uint32_t size); | 
|  |  | 
|  | /* Check if a pointer is aligned on an align-byte boundary */ | 
|  | #define vb2_aligned(ptr, align) (!(((uintptr_t)(ptr)) & ((align) - 1))) | 
|  |  | 
|  | /** | 
|  | * Safer memcmp() for use in crypto. | 
|  | * | 
|  | * Compares the buffers to see if they are equal.  Time taken to perform | 
|  | * the comparison is dependent only on the size, not the relationship of | 
|  | * the match between the buffers.  Note that unlike memcmp(), this only | 
|  | * indicates inequality, not which buffer is lesser. | 
|  | * | 
|  | * @param s1		First buffer | 
|  | * @param s2		Second buffer | 
|  | * @param size		Number of bytes to compare | 
|  | * @return 0 if match or size=0, non-zero if at least one byte mismatched. | 
|  | */ | 
|  | int vb2_safe_memcmp(const void *s1, const void *s2, size_t size); | 
|  |  | 
|  | /** | 
|  | * Align a buffer and check its size. | 
|  | * | 
|  | * @param **ptr		Pointer to pointer to align | 
|  | * @param *size		Points to size of buffer pointed to by *ptr | 
|  | * @param align		Required alignment (must be power of 2) | 
|  | * @param want_size	Required size | 
|  | * @return VB2_SUCCESS, or non-zero if error. | 
|  | */ | 
|  | int vb2_align(uint8_t **ptr, | 
|  | uint32_t *size, | 
|  | uint32_t align, | 
|  | uint32_t want_size); | 
|  |  | 
|  | /** | 
|  | * Return offset of ptr from base. | 
|  | * | 
|  | * @param base		Base pointer | 
|  | * @param ptr		Pointer at some offset from base | 
|  | * @return The offset of ptr from base. | 
|  | */ | 
|  | ptrdiff_t vb2_offset_of(const void *base, const void *ptr); | 
|  |  | 
|  | /** | 
|  | * Return expected signature size for a signature/hash algorithm pair | 
|  | * | 
|  | * @param sig_alg	Signature algorithm | 
|  | * @param hash_alg	Hash algorithm | 
|  | * @return The signature size, or zero if error / unsupported algorithm. | 
|  | */ | 
|  | uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg, | 
|  | enum vb2_hash_algorithm hash_alg); | 
|  |  | 
|  | /** | 
|  | * Return a key ID for an unsigned hash algorithm. | 
|  | * | 
|  | * @param hash_alg	Hash algorithm to return key for | 
|  | * @return A pointer to the key ID for that hash algorithm with | 
|  | *	   sig_alg=VB2_SIG_NONE, or NULL if error. | 
|  | */ | 
|  | const struct vb2_id *vb2_hash_id(enum vb2_hash_algorithm hash_alg); | 
|  |  | 
|  | /* Size of work buffer sufficient for vb2_verify_digest() worst case. */ | 
|  | #define VB2_VERIFY_DIGEST_WORKBUF_BYTES VB2_VERIFY_RSA_DIGEST_WORKBUF_BYTES | 
|  |  | 
|  | /* Size of work buffer sufficient for vb2_verify_data() worst case. */ | 
|  | #define VB2_VERIFY_DATA_WORKBUF_BYTES					\ | 
|  | (VB2_SHA512_DIGEST_SIZE +					\ | 
|  | VB2_MAX(VB2_VERIFY_DIGEST_WORKBUF_BYTES,			\ | 
|  | sizeof(struct vb2_digest_context))) | 
|  |  | 
|  | /* Size of work buffer sufficient for vb2_verify_keyblock() worst case. */ | 
|  | #define VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES | 
|  |  | 
|  | /* Size of work buffer sufficient for vb2_verify_fw_preamble() worst case. */ | 
|  | #define VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES | 
|  |  |