"Das U-Boot" Source Tree
at master 135 lines 2.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* Parse a Microsoft Individual Code Signing blob 3 * 4 * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8#define pr_fmt(fmt) "MSCODE: "fmt 9#include <linux/kernel.h> 10#ifndef __UBOOT__ 11#include <linux/slab.h> 12#endif 13#include <linux/err.h> 14#include <linux/oid_registry.h> 15#include <crypto/pkcs7.h> 16#ifdef __UBOOT__ 17#include <crypto/mscode.h> 18#else 19#include "verify_pefile.h" 20#endif 21#include "mscode.asn1.h" 22 23/* 24 * Parse a Microsoft Individual Code Signing blob 25 */ 26int mscode_parse(void *_ctx, const void *content_data, size_t data_len, 27 size_t asn1hdrlen) 28{ 29 struct pefile_context *ctx = _ctx; 30 31 content_data -= asn1hdrlen; 32 data_len += asn1hdrlen; 33 pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len), 34 content_data); 35 36 return asn1_ber_decoder(&mscode_decoder, ctx, content_data, data_len); 37} 38 39/* 40 * Check the content type OID 41 */ 42int mscode_note_content_type(void *context, size_t hdrlen, 43 unsigned char tag, 44 const void *value, size_t vlen) 45{ 46 enum OID oid; 47 48 oid = look_up_OID(value, vlen); 49 if (oid == OID__NR) { 50 char buffer[50]; 51 52 sprint_oid(value, vlen, buffer, sizeof(buffer)); 53 pr_err("Unknown OID: %s\n", buffer); 54 return -EBADMSG; 55 } 56 57 /* 58 * pesign utility had a bug where it was putting 59 * OID_msIndividualSPKeyPurpose instead of OID_msPeImageDataObjId 60 * So allow both OIDs. 61 */ 62 if (oid != OID_msPeImageDataObjId && 63 oid != OID_msIndividualSPKeyPurpose) { 64 pr_err("Unexpected content type OID %u\n", oid); 65 return -EBADMSG; 66 } 67 68 return 0; 69} 70 71/* 72 * Note the digest algorithm OID 73 */ 74int mscode_note_digest_algo(void *context, size_t hdrlen, 75 unsigned char tag, 76 const void *value, size_t vlen) 77{ 78 struct pefile_context *ctx = context; 79 char buffer[50]; 80 enum OID oid; 81 82 oid = look_up_OID(value, vlen); 83 switch (oid) { 84 case OID_md4: 85 ctx->digest_algo = "md4"; 86 break; 87 case OID_md5: 88 ctx->digest_algo = "md5"; 89 break; 90 case OID_sha1: 91 ctx->digest_algo = "sha1"; 92 break; 93 case OID_sha256: 94 ctx->digest_algo = "sha256"; 95 break; 96 case OID_sha384: 97 ctx->digest_algo = "sha384"; 98 break; 99 case OID_sha512: 100 ctx->digest_algo = "sha512"; 101 break; 102 case OID_sha224: 103 ctx->digest_algo = "sha224"; 104 break; 105 106 case OID__NR: 107 sprint_oid(value, vlen, buffer, sizeof(buffer)); 108 pr_err("Unknown OID: %s\n", buffer); 109 return -EBADMSG; 110 111 default: 112 pr_err("Unsupported content type: %u\n", oid); 113 return -ENOPKG; 114 } 115 116 return 0; 117} 118 119/* 120 * Note the digest we're guaranteeing with this certificate 121 */ 122int mscode_note_digest(void *context, size_t hdrlen, 123 unsigned char tag, 124 const void *value, size_t vlen) 125{ 126 struct pefile_context *ctx = context; 127 128 ctx->digest = kmemdup(value, vlen, GFP_KERNEL); 129 if (!ctx->digest) 130 return -ENOMEM; 131 132 ctx->digest_len = vlen; 133 134 return 0; 135}