/* policy_create.c * * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfBoot. * * wolfBoot is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ /* Tool for creating a policy digest file that is then signed by the key tool * and included in the image header using HDR_POLICY_SIGNATURE. */ #include #include #include #include #include #include "keystore.h" #include "tpm.h" #define DEFAULT_PCR 16 static void usage(void) { printf("Expected usage:\n"); printf("./examples/pcr/policy_create [-pcr=/-pcrmask] [-pcrdigest=] [-out=]\n"); printf("* -pcr=index: SHA2-256 PCR index < 24 (multiple can be supplied) (default %d)\n", DEFAULT_PCR); printf("* -pcrmask=0x00000000: PCR mask (or -pcr= args)\n"); printf("* -pcrdigest=hexstr: PCR Digest (default=Read actual PCR's)\n"); printf("* -out=file: Policy Digest to sign (default policy.bin)\n"); } int writeBin(const char* filename, const uint8_t*buf, word32 bufSz) { int rc = TPM_RC_FAILURE; if (filename == NULL || buf == NULL) return BAD_FUNC_ARG; XFILE fp = NULL; size_t fileSz = 0; fp = XFOPEN(filename, "wt"); if (fp != XBADFILE) { fileSz = XFWRITE(buf, 1, bufSz, fp); /* sanity check */ if (fileSz == (word32)bufSz) { rc = TPM_RC_SUCCESS; } printf("Wrote %d bytes to %s\n", (int)fileSz, filename); XFCLOSE(fp); } return rc; } static signed char hexCharToByte(signed char ch) { signed char ret = (signed char)ch; if (ret >= '0' && ret <= '9') ret -= '0'; else if (ret >= 'A' && ret <= 'F') ret -= 'A' - 10; else if (ret >= 'a' && ret <= 'f') ret -= 'a' - 10; else ret = -1; /* error case - return code must be signed */ return ret; } static int hexToByte(const char *hex, unsigned char *output, unsigned long sz) { int outSz = 0; word32 i; for (i = 0; i < sz; i+=2) { signed char ch1, ch2; ch1 = hexCharToByte(hex[i]); ch2 = hexCharToByte(hex[i+1]); if ((ch1 < 0) || (ch2 < 0)) { return -1; } output[outSz++] = (unsigned char)((ch1 << 4) + ch2); } return outSz; } static void printHexString(const unsigned char* bin, unsigned long sz, unsigned long maxLine) { unsigned long i; printf("\t"); if (maxLine == 0) maxLine = sz; for (i = 0; i < sz; i++) { printf("%02x", bin[i]); if (((i+1) % maxLine) == 0 && i+1 != sz) printf("\n\t"); } printf("\n"); } uint32_t wolfBoot_tpm_pcrmask_sel(uint32_t pcrMask, uint8_t* pcrArray, uint32_t pcrArraySz) { int i; uint32_t pcrArraySzAct = 0; for (i=0; i= 2) { if (XSTRCMP(argv[1], "-?") == 0 || XSTRCMP(argv[1], "-h") == 0 || XSTRCMP(argv[1], "--help") == 0) { usage(); return 0; } } while (argc > 1) { if (XSTRNCMP(argv[argc-1], "-pcr=", XSTRLEN("-pcr=")) == 0) { const char* pcrStr = argv[argc-1] + XSTRLEN("-pcr="); byte pcrIndex = (byte)XATOI(pcrStr); if (pcrIndex > PCR_LAST) { printf("PCR index is out of range (0-23)\n"); usage(); return 0; } pcrArray[pcrArraySz++] = pcrIndex; } else if (XSTRNCMP(argv[argc-1], "-pcrmask=", XSTRLEN("-pcrmask=")) == 0) { const char* pcrMaskStr = argv[argc-1] + XSTRLEN("-pcrmask="); pcrMask = (word32)XSTRTOL(pcrMaskStr, NULL, 0); } else if (XSTRNCMP(argv[argc-1], "-pcrdigest=", XSTRLEN("-pcrdigest=")) == 0) { const char* hashHexStr = argv[argc-1] + XSTRLEN("-pcrdigest="); int hashHexStrLen = (int)XSTRLEN(hashHexStr); if (hashHexStrLen > (int)sizeof(pcrDigest)*2+1) pcrDigestSz = -1; else pcrDigestSz = hexToByte(hashHexStr, pcrDigest, hashHexStrLen); if (pcrDigestSz <= 0) { fprintf(stderr, "Invalid PCR hash length\n"); usage(); return -1; } } else if (XSTRNCMP(argv[argc-1], "-out=", XSTRLEN("-out=")) == 0) { outFile = argv[argc-1] + XSTRLEN("-out="); } else { printf("Warning: Unrecognized option: %s\n", argv[argc-1]); } argc--; } /* Determine PCR's based on mask or default (if none set) */ if (pcrArraySz == 0) { if (pcrMask == 0) { pcrArray[pcrArraySz++] = DEFAULT_PCR; } else { pcrArraySz = wolfBoot_tpm_pcrmask_sel(pcrMask, pcrArray, sizeof(pcrArray)); } } return TPM2_PCR_Policy_Create(pcrAlg, pcrArray, pcrArraySz, outFile, pcrDigest, pcrDigestSz, policyRef, policyRefSz); }