xref: /freebsd/lib/libsecureboot/vectx.c (revision afc571b1a6fb341b0e3f603d4f3a2538093e91f5)
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 #ifndef _STANDALONE
295fff9558SSimon J. Gerraty /* Avoid unwanted userlandish components */
305fff9558SSimon J. Gerraty #define _KERNEL
315fff9558SSimon J. Gerraty #include <sys/errno.h>
325fff9558SSimon J. Gerraty #undef _KERNEL
335fff9558SSimon J. Gerraty #endif
345fff9558SSimon J. Gerraty 
355fff9558SSimon J. Gerraty #include "libsecureboot-priv.h"
36*afc571b1SSimon J. Gerraty #include <verify_file.h>
375fff9558SSimon J. Gerraty 
385fff9558SSimon J. Gerraty /**
395fff9558SSimon J. Gerraty  * @file vectx.c
405fff9558SSimon J. Gerraty  * @brief api to verify file while reading
415fff9558SSimon J. Gerraty  *
425fff9558SSimon J. Gerraty  * This API allows the hash of a file to be computed as it is read.
435fff9558SSimon J. Gerraty  * Key to this is seeking by reading.
445fff9558SSimon J. Gerraty  *
455fff9558SSimon J. Gerraty  * On close an indication of the verification result is returned.
465fff9558SSimon J. Gerraty  */
475fff9558SSimon J. Gerraty 
485fff9558SSimon J. Gerraty struct vectx {
495fff9558SSimon J. Gerraty 	br_hash_compat_context vec_ctx;	/* hash ctx */
505fff9558SSimon J. Gerraty 	const br_hash_class *vec_md;	/* hash method */
515fff9558SSimon J. Gerraty 	const char	*vec_path;	/* path we are verifying */
525fff9558SSimon J. Gerraty 	const char	*vec_want;	/* hash value we want */
535fff9558SSimon J. Gerraty 	off_t		vec_off;	/* current offset */
54*afc571b1SSimon J. Gerraty 	off_t		vec_hashed;	/* where we have hashed to */
555fff9558SSimon J. Gerraty 	size_t		vec_size;	/* size of path */
565fff9558SSimon J. Gerraty 	size_t		vec_hashsz;	/* size of hash */
575fff9558SSimon J. Gerraty 	int		vec_fd;		/* file descriptor */
585fff9558SSimon J. Gerraty 	int		vec_status;	/* verification status */
595fff9558SSimon J. Gerraty };
605fff9558SSimon J. Gerraty 
61*afc571b1SSimon J. Gerraty 
625fff9558SSimon J. Gerraty /**
635fff9558SSimon J. Gerraty  * @brief
645fff9558SSimon J. Gerraty  * verify an open file as we read it
655fff9558SSimon J. Gerraty  *
665fff9558SSimon J. Gerraty  * If the file has no fingerprint to match, we will still return a
675fff9558SSimon J. Gerraty  * verification context containing little more than the file
685fff9558SSimon J. Gerraty  * descriptor, and an error code in @c error.
695fff9558SSimon J. Gerraty  *
705fff9558SSimon J. Gerraty  * @param[in] fd
715fff9558SSimon J. Gerraty  *	open descriptor
725fff9558SSimon J. Gerraty  *
735fff9558SSimon J. Gerraty  * @param[in] path
745fff9558SSimon J. Gerraty  *	pathname to open
755fff9558SSimon J. Gerraty  *
765fff9558SSimon J. Gerraty  * @param[in] off
775fff9558SSimon J. Gerraty  *	current offset
785fff9558SSimon J. Gerraty  *
795fff9558SSimon J. Gerraty  * @param[in] stp
805fff9558SSimon J. Gerraty  *	pointer to struct stat
815fff9558SSimon J. Gerraty  *
825fff9558SSimon J. Gerraty  * @param[out] error
835fff9558SSimon J. Gerraty  *	@li 0 all is good
845fff9558SSimon J. Gerraty  *	@li ENOMEM out of memory
855fff9558SSimon J. Gerraty  *	@li VE_FINGERPRINT_NONE	no entry found
865fff9558SSimon J. Gerraty  *	@li VE_FINGERPRINT_UNKNOWN no fingerprint in entry
875fff9558SSimon J. Gerraty  *
885fff9558SSimon J. Gerraty  * @return ctx or NULL on error.
895fff9558SSimon J. Gerraty  *	NULL is only returned for non-files or out-of-memory.
905fff9558SSimon J. Gerraty  */
915fff9558SSimon J. Gerraty struct vectx *
92*afc571b1SSimon J. Gerraty vectx_open(int fd, const char *path, off_t off, struct stat *stp,
93*afc571b1SSimon J. Gerraty     int *error, const char *caller)
945fff9558SSimon J. Gerraty {
955fff9558SSimon J. Gerraty 	struct vectx *ctx;
965fff9558SSimon J. Gerraty 	struct stat st;
975fff9558SSimon J. Gerraty 	size_t hashsz;
985fff9558SSimon J. Gerraty 	char *cp;
99*afc571b1SSimon J. Gerraty 	int rc;
1005fff9558SSimon J. Gerraty 
101*afc571b1SSimon J. Gerraty 	if (!stp)
1025fff9558SSimon J. Gerraty 	    stp = &st;
1035fff9558SSimon J. Gerraty 
104*afc571b1SSimon J. Gerraty 	rc = verify_prep(fd, path, off, stp, __func__);
105*afc571b1SSimon J. Gerraty 
106*afc571b1SSimon J. Gerraty 	DEBUG_PRINTF(2,
107*afc571b1SSimon J. Gerraty 	    ("vectx_open: caller=%s,name='%s',prep_rc=%d\n",
108*afc571b1SSimon J. Gerraty 		caller,path, rc));
109*afc571b1SSimon J. Gerraty 
110*afc571b1SSimon J. Gerraty 	switch (rc) {
111*afc571b1SSimon J. Gerraty 	case VE_FINGERPRINT_NONE:
112*afc571b1SSimon J. Gerraty 	case VE_FINGERPRINT_UNKNOWN:
113*afc571b1SSimon J. Gerraty 	case VE_FINGERPRINT_WRONG:
114*afc571b1SSimon J. Gerraty 		*error = rc;
1155fff9558SSimon J. Gerraty 		return (NULL);
1165fff9558SSimon J. Gerraty 	}
1175fff9558SSimon J. Gerraty 	ctx = malloc(sizeof(struct vectx));
1185fff9558SSimon J. Gerraty 	if (!ctx)
1195fff9558SSimon J. Gerraty 		goto enomem;
1205fff9558SSimon J. Gerraty 	ctx->vec_fd = fd;
1215fff9558SSimon J. Gerraty 	ctx->vec_path = path;
1225fff9558SSimon J. Gerraty 	ctx->vec_size = stp->st_size;
1235fff9558SSimon J. Gerraty 	ctx->vec_off = 0;
124*afc571b1SSimon J. Gerraty 	ctx->vec_hashed = 0;
1255fff9558SSimon J. Gerraty 	ctx->vec_want = NULL;
1265fff9558SSimon J. Gerraty 	ctx->vec_status = 0;
127*afc571b1SSimon J. Gerraty 	ctx->vec_hashsz = hashsz = 0;
1285fff9558SSimon J. Gerraty 
129*afc571b1SSimon J. Gerraty 	if (rc == 0) {
130*afc571b1SSimon J. Gerraty 		/* we are not verifying this */
131*afc571b1SSimon J. Gerraty 		*error = 0;
132*afc571b1SSimon J. Gerraty 		return (ctx);
133*afc571b1SSimon J. Gerraty 	}
1345fff9558SSimon J. Gerraty 	cp = fingerprint_info_lookup(fd, path);
1355fff9558SSimon J. Gerraty 	if (!cp) {
1365fff9558SSimon J. Gerraty 		ctx->vec_status = VE_FINGERPRINT_NONE;
1375fff9558SSimon J. Gerraty 		ve_error_set("%s: no entry", path);
1385fff9558SSimon J. Gerraty 	} else {
13964ca9a7fSSimon J. Gerraty 		if (strncmp(cp, "no_hash", 7) == 0) {
14064ca9a7fSSimon J. Gerraty 			ctx->vec_status = VE_FINGERPRINT_IGNORE;
14164ca9a7fSSimon J. Gerraty 			hashsz = 0;
14264ca9a7fSSimon J. Gerraty 		} else if (strncmp(cp, "sha256=", 7) == 0) {
1435fff9558SSimon J. Gerraty 			ctx->vec_md = &br_sha256_vtable;
1445fff9558SSimon J. Gerraty 			hashsz = br_sha256_SIZE;
1455fff9558SSimon J. Gerraty 			cp += 7;
1465fff9558SSimon J. Gerraty #ifdef VE_SHA1_SUPPORT
1475fff9558SSimon J. Gerraty 		} else if (strncmp(cp, "sha1=", 5) == 0) {
1485fff9558SSimon J. Gerraty 			ctx->vec_md = &br_sha1_vtable;
1495fff9558SSimon J. Gerraty 			hashsz = br_sha1_SIZE;
1505fff9558SSimon J. Gerraty 			cp += 5;
1515fff9558SSimon J. Gerraty #endif
1525fff9558SSimon J. Gerraty #ifdef VE_SHA384_SUPPORT
1535fff9558SSimon J. Gerraty 		} else if (strncmp(cp, "sha384=", 7) == 0) {
1545fff9558SSimon J. Gerraty 		    ctx->vec_md = &br_sha384_vtable;
1555fff9558SSimon J. Gerraty 		    hashsz = br_sha384_SIZE;
1565fff9558SSimon J. Gerraty 		    cp += 7;
1575fff9558SSimon J. Gerraty #endif
1585fff9558SSimon J. Gerraty #ifdef VE_SHA512_SUPPORT
1595fff9558SSimon J. Gerraty 		} else if (strncmp(cp, "sha512=", 7) == 0) {
1605fff9558SSimon J. Gerraty 		    ctx->vec_md = &br_sha512_vtable;
1615fff9558SSimon J. Gerraty 		    hashsz = br_sha512_SIZE;
1625fff9558SSimon J. Gerraty 		    cp += 7;
1635fff9558SSimon J. Gerraty #endif
1645fff9558SSimon J. Gerraty 		} else {
1655fff9558SSimon J. Gerraty 			ctx->vec_status = VE_FINGERPRINT_UNKNOWN;
1665fff9558SSimon J. Gerraty 			ve_error_set("%s: no supported fingerprint", path);
1675fff9558SSimon J. Gerraty 		}
1685fff9558SSimon J. Gerraty 	}
1695fff9558SSimon J. Gerraty 	*error = ctx->vec_status;
1705fff9558SSimon J. Gerraty 	ctx->vec_hashsz = hashsz;
1715fff9558SSimon J. Gerraty 	ctx->vec_want = cp;
17264ca9a7fSSimon J. Gerraty 	if (hashsz > 0) {
1735fff9558SSimon J. Gerraty 		ctx->vec_md->init(&ctx->vec_ctx.vtable);
1745fff9558SSimon J. Gerraty 
17564ca9a7fSSimon J. Gerraty 		if (off > 0) {
1765fff9558SSimon J. Gerraty 			lseek(fd, 0, SEEK_SET);
1775fff9558SSimon J. Gerraty 			vectx_lseek(ctx, off, SEEK_SET);
1785fff9558SSimon J. Gerraty 		}
17964ca9a7fSSimon J. Gerraty 	}
180*afc571b1SSimon J. Gerraty 	DEBUG_PRINTF(2,
181*afc571b1SSimon J. Gerraty 	    ("vectx_open: caller=%s,name='%s',hashsz=%lu,status=%d\n",
182*afc571b1SSimon J. Gerraty 		caller, path, (unsigned long)ctx->vec_hashsz,
183*afc571b1SSimon J. Gerraty 		ctx->vec_status));
1845fff9558SSimon J. Gerraty 	return (ctx);
1855fff9558SSimon J. Gerraty 
1865fff9558SSimon J. Gerraty enomem:					/* unlikely */
1875fff9558SSimon J. Gerraty 	*error = ENOMEM;
1885fff9558SSimon J. Gerraty 	free(ctx);
1895fff9558SSimon J. Gerraty 	return (NULL);
1905fff9558SSimon J. Gerraty }
1915fff9558SSimon J. Gerraty 
1925fff9558SSimon J. Gerraty /**
1935fff9558SSimon J. Gerraty  * @brief
1945fff9558SSimon J. Gerraty  * read bytes from file and update hash
1955fff9558SSimon J. Gerraty  *
1965fff9558SSimon J. Gerraty  * It is critical that all file I/O comes through here.
1975fff9558SSimon J. Gerraty  * We keep track of current offset.
198*afc571b1SSimon J. Gerraty  * We also track what offset we have hashed to,
199*afc571b1SSimon J. Gerraty  * so we won't replay data if we seek backwards.
2005fff9558SSimon J. Gerraty  *
2015fff9558SSimon J. Gerraty  * @param[in] pctx
2025fff9558SSimon J. Gerraty  *	pointer to ctx
2035fff9558SSimon J. Gerraty  *
2045fff9558SSimon J. Gerraty  * @param[in] buf
2055fff9558SSimon J. Gerraty  *
2065fff9558SSimon J. Gerraty  * @param[in] nbytes
2075fff9558SSimon J. Gerraty  *
2085fff9558SSimon J. Gerraty  * @return bytes read or error.
2095fff9558SSimon J. Gerraty  */
2105fff9558SSimon J. Gerraty ssize_t
2115fff9558SSimon J. Gerraty vectx_read(struct vectx *ctx, void *buf, size_t nbytes)
2125fff9558SSimon J. Gerraty {
2135fff9558SSimon J. Gerraty 	unsigned char *bp = buf;
2145fff9558SSimon J. Gerraty 	int n;
215*afc571b1SSimon J. Gerraty 	int delta;
216*afc571b1SSimon J. Gerraty 	int x;
2175fff9558SSimon J. Gerraty 	size_t off;
2185fff9558SSimon J. Gerraty 
2195fff9558SSimon J. Gerraty 	if (ctx->vec_hashsz == 0)	/* nothing to do */
2205fff9558SSimon J. Gerraty 		return (read(ctx->vec_fd, buf, nbytes));
2215fff9558SSimon J. Gerraty 
2225fff9558SSimon J. Gerraty 	off = 0;
2235fff9558SSimon J. Gerraty 	do {
2245fff9558SSimon J. Gerraty 		n = read(ctx->vec_fd, &bp[off], nbytes - off);
2255fff9558SSimon J. Gerraty 		if (n < 0)
2265fff9558SSimon J. Gerraty 			return (n);
2275fff9558SSimon J. Gerraty 		if (n > 0) {
228*afc571b1SSimon J. Gerraty 			/* we may have seeked backwards! */
229*afc571b1SSimon J. Gerraty 			delta = ctx->vec_hashed - ctx->vec_off;
230*afc571b1SSimon J. Gerraty 			if (delta > 0) {
231*afc571b1SSimon J. Gerraty 				x = MIN(delta, n);
232*afc571b1SSimon J. Gerraty 				off += x;
233*afc571b1SSimon J. Gerraty 				n -= x;
234*afc571b1SSimon J. Gerraty 				ctx->vec_off += x;
235*afc571b1SSimon J. Gerraty 			}
236*afc571b1SSimon J. Gerraty 			if (n > 0) {
2375fff9558SSimon J. Gerraty 				ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], n);
2385fff9558SSimon J. Gerraty 				off += n;
2395fff9558SSimon J. Gerraty 				ctx->vec_off += n;
240*afc571b1SSimon J. Gerraty 				ctx->vec_hashed += n;
241*afc571b1SSimon J. Gerraty 			}
2425fff9558SSimon J. Gerraty 		}
2435fff9558SSimon J. Gerraty 	} while (n > 0 && off < nbytes);
2445fff9558SSimon J. Gerraty 	return (off);
2455fff9558SSimon J. Gerraty }
2465fff9558SSimon J. Gerraty 
2475fff9558SSimon J. Gerraty /**
2485fff9558SSimon J. Gerraty  * @brief
2495fff9558SSimon J. Gerraty  * vectx equivalent of lseek
2505fff9558SSimon J. Gerraty  *
251*afc571b1SSimon J. Gerraty  * When seeking forwards we actually call vectx_read
2525fff9558SSimon J. Gerraty  * to reach the desired offset.
2535fff9558SSimon J. Gerraty  *
254*afc571b1SSimon J. Gerraty  * We support seeking backwards.
2555fff9558SSimon J. Gerraty  *
2565fff9558SSimon J. Gerraty  * @param[in] pctx
2575fff9558SSimon J. Gerraty  *	pointer to ctx
2585fff9558SSimon J. Gerraty  *
2595fff9558SSimon J. Gerraty  * @param[in] off
2605fff9558SSimon J. Gerraty  *	desired offset
2615fff9558SSimon J. Gerraty  *
2625fff9558SSimon J. Gerraty  * @param[in] whence
263*afc571b1SSimon J. Gerraty  * 	We try to convert whence to ``SEEK_SET``.
264*afc571b1SSimon J. Gerraty  *	We do not support ``SEEK_DATA`` or ``SEEK_HOLE``.
2655fff9558SSimon J. Gerraty  *
2665fff9558SSimon J. Gerraty  * @return offset or error.
2675fff9558SSimon J. Gerraty  */
2685fff9558SSimon J. Gerraty off_t
2695fff9558SSimon J. Gerraty vectx_lseek(struct vectx *ctx, off_t off, int whence)
2705fff9558SSimon J. Gerraty {
2715fff9558SSimon J. Gerraty 	unsigned char buf[PAGE_SIZE];
2725fff9558SSimon J. Gerraty 	size_t delta;
2735fff9558SSimon J. Gerraty 	ssize_t n;
2745fff9558SSimon J. Gerraty 
2755fff9558SSimon J. Gerraty 	if (ctx->vec_hashsz == 0)	/* nothing to do */
2765fff9558SSimon J. Gerraty 		return (lseek(ctx->vec_fd, off, whence));
2775fff9558SSimon J. Gerraty 
2785fff9558SSimon J. Gerraty 	/*
279*afc571b1SSimon J. Gerraty 	 * Convert whence to SEEK_SET
2805fff9558SSimon J. Gerraty 	 */
2815fff9558SSimon J. Gerraty 	if (whence == SEEK_END && off <= 0) {
2825fff9558SSimon J. Gerraty 		whence = SEEK_SET;
2835fff9558SSimon J. Gerraty 		off += ctx->vec_size;
284*afc571b1SSimon J. Gerraty 	} else if (whence == SEEK_CUR) {
2855fff9558SSimon J. Gerraty 		whence = SEEK_SET;
2865fff9558SSimon J. Gerraty 		off += ctx->vec_off;
2875fff9558SSimon J. Gerraty 	}
288*afc571b1SSimon J. Gerraty 	if (whence != SEEK_SET ||
2895fff9558SSimon J. Gerraty 	    (size_t)off > ctx->vec_size) {
290*afc571b1SSimon J. Gerraty 		printf("ERROR: %s: unsupported operation: whence=%d off=%lld -> %lld\n",
291*afc571b1SSimon J. Gerraty 		    __func__, whence, (long long)ctx->vec_off, (long long)off);
2925fff9558SSimon J. Gerraty 		return (-1);
2935fff9558SSimon J. Gerraty 	}
294*afc571b1SSimon J. Gerraty 	if (off < ctx->vec_hashed) {
295*afc571b1SSimon J. Gerraty 		/* seeking backwards! just do it */
296*afc571b1SSimon J. Gerraty 		ctx->vec_off = lseek(ctx->vec_fd, off, whence);
297*afc571b1SSimon J. Gerraty 		return (ctx->vec_off);
298*afc571b1SSimon J. Gerraty 	}
2995fff9558SSimon J. Gerraty 	n = 0;
3005fff9558SSimon J. Gerraty 	do {
3015fff9558SSimon J. Gerraty 		delta = off - ctx->vec_off;
3025fff9558SSimon J. Gerraty 		if (delta > 0) {
3035fff9558SSimon J. Gerraty 			delta = MIN(PAGE_SIZE, delta);
3045fff9558SSimon J. Gerraty 			n = vectx_read(ctx, buf, delta);
3055fff9558SSimon J. Gerraty 			if (n < 0)
3065fff9558SSimon J. Gerraty 				return (n);
3075fff9558SSimon J. Gerraty 		}
3085fff9558SSimon J. Gerraty 	} while (ctx->vec_off < off && n > 0);
3095fff9558SSimon J. Gerraty 	return (ctx->vec_off);
3105fff9558SSimon J. Gerraty }
3115fff9558SSimon J. Gerraty 
3125fff9558SSimon J. Gerraty /**
3135fff9558SSimon J. Gerraty  * @brief
3145fff9558SSimon J. Gerraty  * check that hashes match and cleanup
3155fff9558SSimon J. Gerraty  *
3165fff9558SSimon J. Gerraty  * We have finished reading file, compare the hash with what
3175fff9558SSimon J. Gerraty  * we wanted.
3185fff9558SSimon J. Gerraty  *
3195fff9558SSimon J. Gerraty  * @param[in] pctx
3205fff9558SSimon J. Gerraty  *	pointer to ctx
3215fff9558SSimon J. Gerraty  *
3225fff9558SSimon J. Gerraty  * @return 0 or an error.
3235fff9558SSimon J. Gerraty  */
3245fff9558SSimon J. Gerraty int
325*afc571b1SSimon J. Gerraty vectx_close(struct vectx *ctx, int severity, const char *caller)
3265fff9558SSimon J. Gerraty {
3275fff9558SSimon J. Gerraty 	int rc;
3285fff9558SSimon J. Gerraty 
3295fff9558SSimon J. Gerraty 	if (ctx->vec_hashsz == 0) {
3305fff9558SSimon J. Gerraty 		rc = ctx->vec_status;
3315fff9558SSimon J. Gerraty 	} else {
332*afc571b1SSimon J. Gerraty #ifdef VE_PCR_SUPPORT
333*afc571b1SSimon J. Gerraty 		/*
334*afc571b1SSimon J. Gerraty 		 * Only update pcr with things that must verify
335*afc571b1SSimon J. Gerraty 		 * these tend to be processed in a more deterministic
336*afc571b1SSimon J. Gerraty 		 * order, which makes our pseudo pcr more useful.
337*afc571b1SSimon J. Gerraty 		 */
338*afc571b1SSimon J. Gerraty 		ve_pcr_updating_set((severity == VE_MUST));
339*afc571b1SSimon J. Gerraty #endif
3405fff9558SSimon J. Gerraty 		rc = ve_check_hash(&ctx->vec_ctx, ctx->vec_md,
3415fff9558SSimon J. Gerraty 		    ctx->vec_path, ctx->vec_want, ctx->vec_hashsz);
3425fff9558SSimon J. Gerraty 	}
343*afc571b1SSimon J. Gerraty 	DEBUG_PRINTF(2,
344*afc571b1SSimon J. Gerraty 	    ("vectx_close: caller=%s,name='%s',rc=%d,severity=%d\n",
345*afc571b1SSimon J. Gerraty 		caller,ctx->vec_path, rc, severity));
346*afc571b1SSimon J. Gerraty 	if (severity > VE_WANT || rc == VE_FINGERPRINT_WRONG)
347*afc571b1SSimon J. Gerraty 		printf("%serified %s\n", (rc <= 0) ? "Unv" : "V",
348*afc571b1SSimon J. Gerraty 		    ctx->vec_path);
349*afc571b1SSimon J. Gerraty #if !defined(UNIT_TEST) && !defined(DEBUG_VECTX)
350*afc571b1SSimon J. Gerraty 	/* we are generally called with VE_MUST */
351*afc571b1SSimon J. Gerraty 	if (severity > VE_WANT && rc == VE_FINGERPRINT_WRONG)
352*afc571b1SSimon J. Gerraty 		panic("cannot continue");
353*afc571b1SSimon J. Gerraty #endif
3545fff9558SSimon J. Gerraty 	free(ctx);
3555fff9558SSimon J. Gerraty 	return ((rc < 0) ? rc : 0);
3565fff9558SSimon J. Gerraty }
357