Skip to content

Commit

Permalink
Update libsecureboot
Browse files Browse the repository at this point in the history
Preparation for updating bearssl, pull in updates to libsecureboot.

o fix handling of some out-of-memory cases

o allow more control over reporting of Verified/Unverified files.
  this helps boot time when console output is slow

  o recheck verbose/debug level after reading any unverified file

o more debug support for vectx

o hash_string to support fake stat for tftp

o tests/tvo add -v to simply verify signatures

o vets.c allow for HAVE_BR_X509_TIME_CHECK which will greatly simplify
  verification in loader

o report date when certificate fails validity period checks

Reviewed by: stevek
Sponsored by: Juniper Networks, Inc.

(cherry picked from commit 6665541)
  • Loading branch information
sgerraty authored and gbergling committed Apr 14, 2023
1 parent 8dd1299 commit 103a7c7
Show file tree
Hide file tree
Showing 9 changed files with 390 additions and 95 deletions.
3 changes: 3 additions & 0 deletions lib/libsecureboot/h/libsecureboot.h
Expand Up @@ -48,8 +48,11 @@ unsigned char * read_file(const char *, size_t *);
#endif

extern int DebugVe;
extern int VerifyFlags;

#ifndef DEBUG_PRINTF
#define DEBUG_PRINTF(n, x) if (DebugVe >= n) printf x
#endif

int ve_trust_init(void);
size_t ve_trust_anchors_add_buf(unsigned char *, size_t);
Expand Down
11 changes: 9 additions & 2 deletions lib/libsecureboot/h/verify_file.h
Expand Up @@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _VERIFY_FILE_H_
#define _VERIFY_FILE_H_
Expand All @@ -37,6 +35,11 @@
#define VE_UNVERIFIED_OK 0 /* not verified but that's ok */
#define VE_NOT_VERIFYING 2 /* we are not verifying */

/* suitable buf size for hash_string */
#ifndef SHA_DIGEST_LENGTH
# define SHA_DIGEST_LENGTH 20
#endif

struct stat;

int verify_prep(int, const char *, off_t, struct stat *, const char *);
Expand All @@ -47,8 +50,12 @@ int ve_status_get(int);
int load_manifest(const char *, const char *, const char *, struct stat *);
int pass_manifest(const char *, const char *);
int pass_manifest_export_envs(void);
void verify_report(const char *, int, int, struct stat *);
int verify_file(int, const char *, off_t, int, const char *);
void verify_pcr_export(void);
int hash_string(char *s, size_t n, char *buf, size_t bufsz);
int is_verified(struct stat *);
void add_verify_status(struct stat *, int);

struct vectx;
struct vectx* vectx_open(int, const char *, off_t, struct stat *, int *, const char *);
Expand Down
4 changes: 2 additions & 2 deletions lib/libsecureboot/openpgp/opgp_sig.c
Expand Up @@ -369,7 +369,7 @@ openpgp_verify(const char *filename,
#endif

if (rc > 0) {
if ((flags & 1))
if ((flags & VEF_VERBOSE))
printf("Verified %s signed by %s\n",
filename,
key->user ? key->user->name : "someone");
Expand Down Expand Up @@ -447,7 +447,7 @@ openpgp_verify_file(const char *filename, unsigned char *fdata, size_t nbytes)
return (-1);
}
sdata = read_file(sname, &sz);
return (openpgp_verify(filename, fdata, nbytes, sdata, sz, 1));
return (openpgp_verify(filename, fdata, nbytes, sdata, sz, VerifyFlags));
}
#endif

Expand Down
38 changes: 24 additions & 14 deletions lib/libsecureboot/readfile.c
Expand Up @@ -34,20 +34,22 @@ read_fd(int fd, size_t len)
unsigned char *buf;

buf = malloc(len + 1);
for (x = 0, m = len; m > 0; ) {
n = read(fd, &buf[x], m);
if (n < 0)
break;
if (n > 0) {
m -= n;
x += n;
if (buf != NULL) {
for (x = 0, m = len; m > 0; ) {
n = read(fd, &buf[x], m);
if (n < 0)
break;
if (n > 0) {
m -= n;
x += n;
}
}
if (m == 0) {
buf[len] = '\0';
return (buf);
}
free(buf);
}
if (m == 0) {
buf[len] = '\0';
return (buf);
}
free(buf);
return (NULL);
}

Expand All @@ -65,8 +67,16 @@ read_file(const char *path, size_t *len)
fstat(fd, &st);
ucp = read_fd(fd, st.st_size);
close(fd);
if (len != NULL && ucp != NULL)
*len = st.st_size;
if (ucp != NULL) {
if (len != NULL)
*len = st.st_size;
}
#ifdef _STANDALONE
else
printf("%s: out of memory! %lu\n", __func__,
(unsigned long)len);
#endif

return (ucp);
}

45 changes: 31 additions & 14 deletions lib/libsecureboot/tests/tvo.c
Expand Up @@ -31,6 +31,12 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <verify_file.h>

/* keep clang quiet */
extern char *Destdir;
extern size_t DestdirLen;
extern char *Skip;
extern time_t ve_utc;

size_t DestdirLen;
char *Destdir;
char *Skip;
Expand All @@ -42,20 +48,20 @@ main(int argc, char *argv[])
int fd;
int c;
int Vflag;
int vflag;
char *cp;
char *prefix;
char *destdir;

Destdir = NULL;
DestdirLen = 0;
prefix = NULL;
Skip = NULL;

n = ve_trust_init();
printf("Trust %d\n", n);
Vflag = 0;
vflag = 0;

while ((c = getopt(argc, argv, "D:dp:s:T:V")) != -1) {
while ((c = getopt(argc, argv, "D:dp:s:T:u:Vv")) != -1) {
switch (c) {
case 'D':
Destdir = optarg;
Expand All @@ -77,17 +83,25 @@ main(int argc, char *argv[])
case 'V':
Vflag = 1;
break;
case 'v':
vflag = 1;
break;
case 'u':
ve_utc = (time_t)atoi(optarg);
break;
default:
errx(1, "unknown option: -%c", c);
break;
}
}

if (!vflag) {
printf("Trust %d\n", n);
#ifdef VE_PCR_SUPPORT
ve_pcr_updating_set(1);
ve_pcr_updating_set(1);
#endif
ve_self_tests();

ve_self_tests();
}
for ( ; optind < argc; optind++) {
if (Vflag) {
/*
Expand All @@ -113,8 +127,9 @@ main(int argc, char *argv[])
if (cp) {
printf("Verified: %s: %.28s...\n",
argv[optind], cp);
fingerprint_info_add(argv[optind],
prefix, Skip, cp, NULL);
if (!vflag)
fingerprint_info_add(argv[optind],
prefix, Skip, cp, NULL);
} else {
fprintf(stderr, "%s: %s\n",
argv[optind], ve_error_get());
Expand All @@ -126,8 +141,9 @@ main(int argc, char *argv[])
if (cp) {
printf("Verified: %s: %.28s...\n",
argv[optind], cp);
fingerprint_info_add(argv[optind],
prefix, Skip, cp, NULL);
if (!vflag)
fingerprint_info_add(argv[optind],
prefix, Skip, cp, NULL);
} else {
fprintf(stderr, "%s: %s\n",
argv[optind], ve_error_get());
Expand All @@ -150,7 +166,8 @@ main(int argc, char *argv[])
char buf[BUFSIZ];
struct stat st;
int error;
size_t off, n;
off_t off;
size_t nb;

fstat(fd, &st);
lseek(fd, 0, SEEK_SET);
Expand All @@ -167,10 +184,10 @@ main(int argc, char *argv[])
/* we can seek backwards! */
off = vectx_lseek(vp, off/2, SEEK_SET);
if (off < st.st_size) {
n = vectx_read(vp, buf,
nb = vectx_read(vp, buf,
sizeof(buf));
if (n > 0)
off += n;
if (nb > 0)
off += nb;
}
off = vectx_lseek(vp, 0, SEEK_END);
/* repeating that should be harmless */
Expand Down
50 changes: 42 additions & 8 deletions lib/libsecureboot/vectx.c
Expand Up @@ -32,6 +32,11 @@ __FBSDID("$FreeBSD$");
#undef _KERNEL
#endif

#ifdef VECTX_DEBUG
static int vectx_debug = VECTX_DEBUG;
# define DEBUG_PRINTF(n, x) if (vectx_debug >= n) printf x
#endif

#include "libsecureboot-priv.h"
#include <verify_file.h>

Expand All @@ -52,10 +57,11 @@ struct vectx {
const char *vec_want; /* hash value we want */
off_t vec_off; /* current offset */
off_t vec_hashed; /* where we have hashed to */
size_t vec_size; /* size of path */
off_t vec_size; /* size of path */
size_t vec_hashsz; /* size of hash */
int vec_fd; /* file descriptor */
int vec_status; /* verification status */
int vec_closing; /* we are closing */
};


Expand Down Expand Up @@ -125,6 +131,7 @@ vectx_open(int fd, const char *path, off_t off, struct stat *stp,
ctx->vec_want = NULL;
ctx->vec_status = 0;
ctx->vec_hashsz = hashsz = 0;
ctx->vec_closing = 0;

if (rc == 0) {
/* we are not verifying this */
Expand Down Expand Up @@ -229,6 +236,12 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes)
x = nbytes - off;
x = MIN(PAGE_SIZE, x);
d = n = read(ctx->vec_fd, &bp[off], x);
if (ctx->vec_closing && n < x) {
DEBUG_PRINTF(3,
("%s: read %d off=%ld hashed=%ld size=%ld\n",
__func__, n, (long)ctx->vec_off,
(long)ctx->vec_hashed, (long)ctx->vec_size));
}
if (n < 0) {
return (n);
}
Expand All @@ -242,6 +255,12 @@ vectx_read(struct vectx *ctx, void *buf, size_t nbytes)
ctx->vec_off += x;
}
if (d > 0) {
if (ctx->vec_closing && d < PAGE_SIZE) {
DEBUG_PRINTF(3,
("%s: update %ld + %d\n",
__func__,
(long)ctx->vec_hashed, d));
}
ctx->vec_md->update(&ctx->vec_ctx.vtable, &bp[off], d);
off += d;
ctx->vec_off += d;
Expand Down Expand Up @@ -286,20 +305,37 @@ vectx_lseek(struct vectx *ctx, off_t off, int whence)
/*
* Convert whence to SEEK_SET
*/
DEBUG_PRINTF(3,
("%s(%s, %ld, %d)\n", __func__, ctx->vec_path, (long)off, whence));
if (whence == SEEK_END && off <= 0) {
if (ctx->vec_closing && ctx->vec_hashed < ctx->vec_size) {
DEBUG_PRINTF(3, ("%s: SEEK_END %ld\n",
__func__,
(long)(ctx->vec_size - ctx->vec_hashed)));
}
whence = SEEK_SET;
off += ctx->vec_size;
} else if (whence == SEEK_CUR) {
whence = SEEK_SET;
off += ctx->vec_off;
}
if (whence != SEEK_SET ||
(size_t)off > ctx->vec_size) {
printf("ERROR: %s: unsupported operation: whence=%d off=%lld -> %lld\n",
__func__, whence, (long long)ctx->vec_off, (long long)off);
off > ctx->vec_size) {
printf("ERROR: %s: unsupported operation: whence=%d off=%ld -> %ld\n",
__func__, whence, (long)ctx->vec_off, (long)off);
return (-1);
}
if (off < ctx->vec_hashed) {
#ifdef _STANDALONE
struct open_file *f = fd2open_file(ctx->vec_fd);

if (f != NULL &&
strncmp(f->f_ops->fs_name, "tftp", 4) == 0) {
/* we cannot rewind if we've hashed much of the file */
if (ctx->vec_hashed > ctx->vec_size / 5)
return (-1); /* refuse! */
}
#endif
/* seeking backwards! just do it */
ctx->vec_off = lseek(ctx->vec_fd, off, whence);
return (ctx->vec_off);
Expand Down Expand Up @@ -337,6 +373,7 @@ vectx_close(struct vectx *ctx, int severity, const char *caller)
{
int rc;

ctx->vec_closing = 1;
if (ctx->vec_hashsz == 0) {
rc = ctx->vec_status;
} else {
Expand All @@ -356,16 +393,13 @@ vectx_close(struct vectx *ctx, int severity, const char *caller)
DEBUG_PRINTF(2,
("vectx_close: caller=%s,name='%s',rc=%d,severity=%d\n",
caller,ctx->vec_path, rc, severity));
verify_report(ctx->vec_path, severity, rc, NULL);
if (rc == VE_FINGERPRINT_WRONG) {
printf("Unverified: %s\n", ve_error_get());
#if !defined(UNIT_TEST) && !defined(DEBUG_VECTX)
/* we are generally called with VE_MUST */
if (severity > VE_WANT)
panic("cannot continue");
#endif
} else if (severity > VE_WANT) {
printf("%serified %s\n", (rc <= 0) ? "Unv" : "V",
ctx->vec_path);
}
free(ctx);
return ((rc < 0) ? rc : 0);
Expand Down
13 changes: 10 additions & 3 deletions lib/libsecureboot/veopen.c
Expand Up @@ -77,6 +77,13 @@ fingerprint_info_add(const char *filename, const char *prefix,

fingerprint_info_init();
nfip = malloc(sizeof(struct fingerprint_info));
if (nfip == NULL) {
#ifdef _STANDALONE
printf("%s: out of memory! %lu\n", __func__,
(unsigned long)sizeof(struct fingerprint_info));
#endif
return;
}
if (prefix) {
nfip->fi_prefix = strdup(prefix);
} else {
Expand Down Expand Up @@ -115,10 +122,9 @@ fingerprint_info_add(const char *filename, const char *prefix,
if (n == 0)
break;
}
nfip->fi_dev = stp->st_dev;
#ifdef UNIT_TEST
nfip->fi_dev = 0;
#else
nfip->fi_dev = stp->st_dev;
#endif
nfip->fi_data = data;
nfip->fi_prefix_len = strlen(nfip->fi_prefix);
Expand Down Expand Up @@ -198,9 +204,10 @@ fingerprint_info_lookup(int fd, const char *path)
n = strlcpy(pbuf, path, sizeof(pbuf));
if (n >= sizeof(pbuf))
return (NULL);
#ifndef UNIT_TEST
if (fstat(fd, &st) == 0)
dev = st.st_dev;
#ifdef UNIT_TEST
dev = 0;
#endif
/*
* get the first entry - it will have longest prefix
Expand Down

0 comments on commit 103a7c7

Please sign in to comment.