| /* 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 | 
 |  |