uboot/lib/crypto/mscode_parser.c
<<
>>
Prefs
   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}
 136