From owner-svn-src-all@freebsd.org Fri Apr 26 11:12:56 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D4D261590C5F; Fri, 26 Apr 2019 11:12:55 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 5188B8EAB3; Fri, 26 Apr 2019 11:12:55 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DFB52AB33; Fri, 26 Apr 2019 11:12:53 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x3QBCr6e017178; Fri, 26 Apr 2019 11:12:53 GMT (envelope-from mw@FreeBSD.org) Received: (from mw@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x3QBCpiC017168; Fri, 26 Apr 2019 11:12:51 GMT (envelope-from mw@FreeBSD.org) Message-Id: <201904261112.x3QBCpiC017168@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mw set sender to mw@FreeBSD.org using -f From: Marcin Wojtas Date: Fri, 26 Apr 2019 11:12:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r346737 - in stable/12: lib/libsecureboot lib/libsecureboot/h share/mk stand stand/common sys/conf sys/security/mac_veriexec_parser tools/build/options X-SVN-Group: stable-12 X-SVN-Commit-Author: mw X-SVN-Commit-Paths: in stable/12: lib/libsecureboot lib/libsecureboot/h share/mk stand stand/common sys/conf sys/security/mac_veriexec_parser tools/build/options X-SVN-Commit-Revision: 346737 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 5188B8EAB3 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-0.99)[-0.995,0]; NEURAL_HAM_SHORT(-0.96)[-0.965,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Apr 2019 11:12:56 -0000 Author: mw Date: Fri Apr 26 11:12:51 2019 New Revision: 346737 URL: https://svnweb.freebsd.org/changeset/base/346737 Log: MFC r345830: Create kernel module to parse Veriexec manifest based on envs Submitted by: Kornel Duleba Obtained from: Semihalf Sponsored by: Stormshield Added: stable/12/lib/libsecureboot/pass_manifest.c - copied unchanged from r345830, head/lib/libsecureboot/pass_manifest.c stable/12/sys/security/mac_veriexec_parser/ - copied from r345830, head/sys/security/mac_veriexec_parser/ stable/12/tools/build/options/WITH_LOADER_VERIEXEC_PASS_MANFIEST - copied unchanged from r345830, head/tools/build/options/WITH_LOADER_VERIEXEC_PASS_MANFIEST Modified: stable/12/lib/libsecureboot/Makefile.libsa.inc stable/12/lib/libsecureboot/h/verify_file.h stable/12/lib/libsecureboot/libsecureboot-priv.h stable/12/lib/libsecureboot/verify_file.c stable/12/share/mk/src.opts.mk stable/12/stand/common/boot.c stable/12/stand/common/module.c stable/12/stand/loader.mk stable/12/sys/conf/files Modified: stable/12/lib/libsecureboot/Makefile.libsa.inc ============================================================================== --- stable/12/lib/libsecureboot/Makefile.libsa.inc Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/lib/libsecureboot/Makefile.libsa.inc Fri Apr 26 11:12:51 2019 (r346737) @@ -29,6 +29,11 @@ CFLAGS+= \ -I${SRCTOP}/stand/efi/include/${MACHINE} .endif +.if ${MK_LOADER_VERIEXEC_PASS_MANIFEST} == "yes" +SRCS+= \ + pass_manifest.c +.endif + # this is the list of paths (relative to a file # that we need to verify) used to find a signed manifest. # the signature extensions in VE_SIGNATURE_EXT_LIST Modified: stable/12/lib/libsecureboot/h/verify_file.h ============================================================================== --- stable/12/lib/libsecureboot/h/verify_file.h Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/lib/libsecureboot/h/verify_file.h Fri Apr 26 11:12:51 2019 (r346737) @@ -32,6 +32,7 @@ #define VE_WANT 1 /* we want this verified */ #define VE_MUST 2 /* this must be verified */ +#define VE_NOT_CHECKED -42 #define VE_VERIFIED 1 /* all good */ #define VE_UNVERIFIED_OK 0 /* not verified but that's ok */ #define VE_NOT_VERIFYING 2 /* we are not verifying */ @@ -42,6 +43,8 @@ void ve_debug_set(int); int ve_status_get(int); void ve_efi_init(void); int load_manifest(const char *, const char *, const char *, struct stat *); +int pass_manifest(const char *, const char *); +int pass_manifest_export_envs(void); int verify_file(int, const char *, off_t, int); void verify_pcr_export(void); Modified: stable/12/lib/libsecureboot/libsecureboot-priv.h ============================================================================== --- stable/12/lib/libsecureboot/libsecureboot-priv.h Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/lib/libsecureboot/libsecureboot-priv.h Fri Apr 26 11:12:51 2019 (r346737) @@ -31,6 +31,8 @@ /* public api */ #include "libsecureboot.h" +struct stat; + typedef struct { unsigned char *data; size_t hash_size; @@ -49,6 +51,9 @@ int verify_rsa_digest(br_rsa_public_key *pkey, const unsigned char *hash_oid, unsigned char *mdata, size_t mlen, unsigned char *sdata, size_t slen); + +int is_verified(struct stat *stp); +void add_verify_status(struct stat *stp, int status); int openpgp_self_tests(void); Copied: stable/12/lib/libsecureboot/pass_manifest.c (from r345830, head/lib/libsecureboot/pass_manifest.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/lib/libsecureboot/pass_manifest.c Fri Apr 26 11:12:51 2019 (r346737, copy of r345830, head/lib/libsecureboot/pass_manifest.c) @@ -0,0 +1,152 @@ +/*- + * Copyright (c) 2019 Stormshield. + * Copyright (c) 2019 Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY 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$ + */ +#include +__FBSDID("$FreeBSD$"); + +#include + +#include "libsecureboot-priv.h" +#include + +/* + * Values to pass to kernel by envs. + */ +static char manifest_path[MAXPATHLEN]; +static char manifest_prefix[MAXPATHLEN]; +static char manifest_hash[2 * br_sha256_SIZE + 2]; +static int manifest_present = 0; + +/* + * Verify and pass manifest path and digest to kernel through envs. + * The paths in manifest can be either absolute, + * or "prefix", if exists will be added to the ones that are not. + */ +int +pass_manifest(const char *path, const char *prefix) +{ + char *content; + struct stat st; + unsigned char digest[br_sha256_SIZE]; + const br_hash_class *md; + br_hash_compat_context ctx; + int rc; + + content = NULL; + md = &br_sha256_vtable; + + if (strnlen(path, MAXPATHLEN) == MAXPATHLEN || + strnlen(prefix, MAXPATHLEN) == MAXPATHLEN) + return (EINVAL); + + rc = stat(path, &st); + if (rc != 0) + goto out; + + if (!S_ISREG(st.st_mode)) { + rc = EINVAL; + goto out; + } + + rc = is_verified(&st); + + if (rc != VE_NOT_CHECKED && rc != VE_VERIFIED) { + rc = EPERM; + goto out; + } + + if (rc == VE_VERIFIED) + content = read_file(path, NULL); + else + content = (char *)verify_signed(path, VEF_VERBOSE); + + if (content == NULL) { + add_verify_status(&st, VE_FINGERPRINT_WRONG); + rc = EIO; + goto out; + } + + add_verify_status(&st, VE_VERIFIED); + + md->init(&ctx.vtable); + md->update(&ctx.vtable, content, st.st_size); + md->out(&ctx.vtable, digest); + + if (prefix == NULL) + manifest_prefix[0] = '\0'; + else + strcpy(manifest_prefix, prefix); + + strcpy(manifest_path, path); + + hexdigest(manifest_hash, 2 * br_sha256_SIZE + 2, + digest, br_sha256_SIZE); + manifest_hash[2*br_sha256_SIZE] = '\0'; + + manifest_present = 1; + rc = 0; + +out: + if (content != NULL) + free(content); + + return (rc); +} + +/* + * Set appropriate envs to inform kernel about manifest location and digest. + * This should be called right before boot so that envs can't be replaced. + */ +int +pass_manifest_export_envs() +{ + int rc; + + /* If we have nothing to pass make sure that envs are empty. */ + if (!manifest_present) { + unsetenv("veriexec.manifest_path"); + unsetenv("veriexec.manifest_hash"); + unsetenv("veriexec.manifest_prefix"); + return (0); + } + + rc = setenv("veriexec.manifest_path", manifest_path, 1); + if (rc != 0) + return (rc); + + rc = setenv("veriexec.manifest_hash", manifest_hash, 1); + if (rc != 0) { + unsetenv("veriexec.manifest_path"); + return (rc); + } + + if (manifest_prefix[0] != '\0') + rc = setenv("veriexec.manifest_prefix", manifest_prefix, 1); + + return (rc); +} + Modified: stable/12/lib/libsecureboot/verify_file.c ============================================================================== --- stable/12/lib/libsecureboot/verify_file.c Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/lib/libsecureboot/verify_file.c Fri Apr 26 11:12:51 2019 (r346737) @@ -36,8 +36,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define VE_NOT_CHECKED -42 - #ifdef UNIT_TEST # include # define panic warn @@ -112,7 +110,7 @@ struct verify_status { struct verify_status *vs_next; }; -static int +int is_verified(struct stat *stp) { struct verify_status *vsp; @@ -126,7 +124,7 @@ is_verified(struct stat *stp) } /* most recent first, since most likely to see repeated calls. */ -static void +void add_verify_status(struct stat *stp, int status) { struct verify_status *vsp; Modified: stable/12/share/mk/src.opts.mk ============================================================================== --- stable/12/share/mk/src.opts.mk Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/share/mk/src.opts.mk Fri Apr 26 11:12:51 2019 (r346737) @@ -200,6 +200,7 @@ __DEFAULT_NO_OPTIONS = \ LIBSOFT \ LOADER_FIREWIRE \ LOADER_FORCE_LE \ + LOADER_VERIEXEC_PASS_MANIFEST \ NAND \ OFED_EXTRA \ OPENLDAP \ @@ -543,6 +544,10 @@ MK_LLDB:= no MK_CLANG_EXTRAS:= no MK_CLANG_FULL:= no MK_LLVM_COV:= no +.endif + +.if ${MK_LOADER_VERIEXEC} == "no" +MK_LOADER_VERIEXEC_PASS_MANIFEST := no .endif # Modified: stable/12/stand/common/boot.c ============================================================================== --- stable/12/stand/common/boot.c Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/stand/common/boot.c Fri Apr 26 11:12:51 2019 (r346737) @@ -108,6 +108,9 @@ command_boot(int argc, char *argv[]) #ifdef LOADER_VERIEXEC verify_pcr_export(); /* for measured boot */ +#ifdef LOADER_VERIEXEC_PASS_MANIFEST + pass_manifest_export_envs(); +#endif #endif /* Call the exec handler from the loader matching the kernel */ Modified: stable/12/stand/common/module.c ============================================================================== --- stable/12/stand/common/module.c Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/stand/common/module.c Fri Apr 26 11:12:51 2019 (r346737) @@ -159,6 +159,13 @@ command_load(int argc, char *argv[]) ve_debug_set(dflag); return (load_manifest(argv[1], prefix, skip, NULL)); } +#ifdef LOADER_VERIEXEC_PASS_MANIFEST + if (strncmp(typestr, "pass_manifest", 13) == 0) { + if (dflag > 0) + ve_debug_set(dflag); + return (pass_manifest(argv[1], prefix)); + } +#endif #endif fp = file_findfile(argv[1], typestr); Modified: stable/12/stand/loader.mk ============================================================================== --- stable/12/stand/loader.mk Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/stand/loader.mk Fri Apr 26 11:12:51 2019 (r346737) @@ -77,6 +77,10 @@ SRCS+= interp_simple.c CFLAGS+= -DLOADER_VERIEXEC -I${SRCTOP}/lib/libsecureboot/h .endif +.if ${MK_LOADER_VERIEXEC_PASS_MANIFEST} != "no" +CFLAGS+= -DLOADER_VERIEXEC_PASS_MANIFEST -I${SRCTOP}/lib/libsecureboot/h +.endif + .if defined(BOOT_PROMPT_123) CFLAGS+= -DBOOT_PROMPT_123 .endif Modified: stable/12/sys/conf/files ============================================================================== --- stable/12/sys/conf/files Fri Apr 26 09:06:29 2019 (r346736) +++ stable/12/sys/conf/files Fri Apr 26 11:12:51 2019 (r346737) @@ -4934,14 +4934,15 @@ security/mac_portacl/mac_portacl.c optional mac_portac security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test -security/mac_veriexec/mac_veriexec.c optional mac_veriexec -security/mac_veriexec/veriexec_fingerprint.c optional mac_veriexec -security/mac_veriexec/veriexec_metadata.c optional mac_veriexec -security/mac_veriexec/mac_veriexec_rmd160.c optional mac_veriexec_rmd160 -security/mac_veriexec/mac_veriexec_sha1.c optional mac_veriexec_sha1 -security/mac_veriexec/mac_veriexec_sha256.c optional mac_veriexec_sha256 -security/mac_veriexec/mac_veriexec_sha384.c optional mac_veriexec_sha384 -security/mac_veriexec/mac_veriexec_sha512.c optional mac_veriexec_sha512 +security/mac_veriexec/mac_veriexec.c optional mac_veriexec +security/mac_veriexec/veriexec_fingerprint.c optional mac_veriexec +security/mac_veriexec/veriexec_metadata.c optional mac_veriexec +security/mac_veriexec_parser/mac_veriexec_parser.c optional mac_veriexec mac_veriexec_parser +security/mac_veriexec/mac_veriexec_rmd160.c optional mac_veriexec_rmd160 +security/mac_veriexec/mac_veriexec_sha1.c optional mac_veriexec_sha1 +security/mac_veriexec/mac_veriexec_sha256.c optional mac_veriexec_sha256 +security/mac_veriexec/mac_veriexec_sha384.c optional mac_veriexec_sha384 +security/mac_veriexec/mac_veriexec_sha512.c optional mac_veriexec_sha512 teken/teken.c optional sc | vt ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_balloc.c optional ffs Copied: stable/12/tools/build/options/WITH_LOADER_VERIEXEC_PASS_MANFIEST (from r345830, head/tools/build/options/WITH_LOADER_VERIEXEC_PASS_MANFIEST) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/tools/build/options/WITH_LOADER_VERIEXEC_PASS_MANFIEST Fri Apr 26 11:12:51 2019 (r346737, copy of r345830, head/tools/build/options/WITH_LOADER_VERIEXEC_PASS_MANFIEST) @@ -0,0 +1,8 @@ +.\" $FreeBSD$ +Enable building +.Xr loader 8 +with support to pass a verified manifest to kernel. +Kernel has to be build with a module to parse the manfiest. +.Pp +It depends on +.Va WITH_LOADER_VERIEXEC