15fff9558SSimon J. Gerraty /*- 25fff9558SSimon J. Gerraty * Copyright (c) 2018, Juniper Networks, Inc. 35fff9558SSimon J. Gerraty * 45fff9558SSimon J. Gerraty * Redistribution and use in source and binary forms, with or without 55fff9558SSimon J. Gerraty * modification, are permitted provided that the following conditions 65fff9558SSimon J. Gerraty * are met: 75fff9558SSimon J. Gerraty * 1. Redistributions of source code must retain the above copyright 85fff9558SSimon J. Gerraty * notice, this list of conditions and the following disclaimer. 95fff9558SSimon J. Gerraty * 2. Redistributions in binary form must reproduce the above copyright 105fff9558SSimon J. Gerraty * notice, this list of conditions and the following disclaimer in the 115fff9558SSimon J. Gerraty * documentation and/or other materials provided with the distribution. 125fff9558SSimon J. Gerraty * 135fff9558SSimon J. Gerraty * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 145fff9558SSimon J. Gerraty * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 155fff9558SSimon J. Gerraty * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 165fff9558SSimon J. Gerraty * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 175fff9558SSimon J. Gerraty * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 185fff9558SSimon J. Gerraty * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 195fff9558SSimon J. Gerraty * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 205fff9558SSimon J. Gerraty * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 215fff9558SSimon J. Gerraty * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225fff9558SSimon J. Gerraty * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 235fff9558SSimon J. Gerraty * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245fff9558SSimon J. Gerraty */ 255fff9558SSimon J. Gerraty #include <sys/cdefs.h> 265fff9558SSimon J. Gerraty __FBSDID("$FreeBSD$"); 275fff9558SSimon J. Gerraty 285fff9558SSimon J. Gerraty #include "libsecureboot-priv.h" 295fff9558SSimon J. Gerraty 305fff9558SSimon J. Gerraty /* 315fff9558SSimon J. Gerraty * To support measured boot without putting a ton 325fff9558SSimon J. Gerraty * of extra code in the loader, we just maintain 335fff9558SSimon J. Gerraty * a hash of all the hashes we (attempt to) verify. 345fff9558SSimon J. Gerraty * The loader can export this for kernel or rc script 355fff9558SSimon J. Gerraty * to feed to a TPM pcr register - hence the name ve_pcr. 365fff9558SSimon J. Gerraty * 375fff9558SSimon J. Gerraty * NOTE: in the current standard the TPM pcr register size is for SHA1, 385fff9558SSimon J. Gerraty * the fact that we provide a SHA256 hash should not matter 395fff9558SSimon J. Gerraty * as long as we are consistent - it can be truncated or hashed 405fff9558SSimon J. Gerraty * before feeding to TPM. 415fff9558SSimon J. Gerraty */ 425fff9558SSimon J. Gerraty 435fff9558SSimon J. Gerraty static const br_hash_class *pcr_md = NULL; 445fff9558SSimon J. Gerraty static br_hash_compat_context pcr_ctx; 455fff9558SSimon J. Gerraty static size_t pcr_hlen = 0; 46*980bde58SSimon J. Gerraty static int pcr_updating; 475fff9558SSimon J. Gerraty 485fff9558SSimon J. Gerraty /** 495fff9558SSimon J. Gerraty * @brief initialize pcr context 505fff9558SSimon J. Gerraty * 515fff9558SSimon J. Gerraty * Real TPM registers only hold a SHA1 hash 525fff9558SSimon J. Gerraty * but we use SHA256 535fff9558SSimon J. Gerraty */ 545fff9558SSimon J. Gerraty void 555fff9558SSimon J. Gerraty ve_pcr_init(void) 565fff9558SSimon J. Gerraty { 57*980bde58SSimon J. Gerraty pcr_updating = 0; 585fff9558SSimon J. Gerraty pcr_hlen = br_sha256_SIZE; 595fff9558SSimon J. Gerraty pcr_md = &br_sha256_vtable; 605fff9558SSimon J. Gerraty pcr_md->init(&pcr_ctx.vtable); 615fff9558SSimon J. Gerraty } 625fff9558SSimon J. Gerraty 635fff9558SSimon J. Gerraty /** 64*980bde58SSimon J. Gerraty * @brief get pcr_updating state 65*980bde58SSimon J. Gerraty */ 66*980bde58SSimon J. Gerraty int 67*980bde58SSimon J. Gerraty ve_pcr_updating_get(void) 68*980bde58SSimon J. Gerraty { 69*980bde58SSimon J. Gerraty return (pcr_updating); 70*980bde58SSimon J. Gerraty } 71*980bde58SSimon J. Gerraty 72*980bde58SSimon J. Gerraty /** 73*980bde58SSimon J. Gerraty * @brief set pcr_updating state 74*980bde58SSimon J. Gerraty */ 75*980bde58SSimon J. Gerraty void 76*980bde58SSimon J. Gerraty ve_pcr_updating_set(int updating) 77*980bde58SSimon J. Gerraty { 78*980bde58SSimon J. Gerraty pcr_updating = updating; 79*980bde58SSimon J. Gerraty } 80*980bde58SSimon J. Gerraty 81*980bde58SSimon J. Gerraty /** 825fff9558SSimon J. Gerraty * @brief update pcr context 835fff9558SSimon J. Gerraty */ 845fff9558SSimon J. Gerraty void 855fff9558SSimon J. Gerraty ve_pcr_update(unsigned char *data, size_t dlen) 865fff9558SSimon J. Gerraty { 87*980bde58SSimon J. Gerraty if (pcr_updating != 0 && pcr_md != NULL) 885fff9558SSimon J. Gerraty pcr_md->update(&pcr_ctx.vtable, data, dlen); 895fff9558SSimon J. Gerraty } 905fff9558SSimon J. Gerraty 915fff9558SSimon J. Gerraty /** 925fff9558SSimon J. Gerraty * @brief get pcr result 935fff9558SSimon J. Gerraty */ 945fff9558SSimon J. Gerraty ssize_t 955fff9558SSimon J. Gerraty ve_pcr_get(unsigned char *buf, size_t sz) 965fff9558SSimon J. Gerraty { 975fff9558SSimon J. Gerraty if (!pcr_md) 985fff9558SSimon J. Gerraty return (-1); 995fff9558SSimon J. Gerraty if (sz < pcr_hlen) 1005fff9558SSimon J. Gerraty return (-1); 1015fff9558SSimon J. Gerraty pcr_md->out(&pcr_ctx.vtable, buf); 1025fff9558SSimon J. Gerraty return (pcr_hlen); 1035fff9558SSimon J. Gerraty } 1045fff9558SSimon J. Gerraty 105