linux/crypto/rsa_helper.c
<<
>>
Prefs
   1/*
   2 * RSA key extract helper
   3 *
   4 * Copyright (c) 2015, Intel Corporation
   5 * Authors: Tadeusz Struk <tadeusz.struk@intel.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License as published by the Free
   9 * Software Foundation; either version 2 of the License, or (at your option)
  10 * any later version.
  11 *
  12 */
  13#include <linux/kernel.h>
  14#include <linux/export.h>
  15#include <linux/err.h>
  16#include <linux/fips.h>
  17#include <crypto/internal/rsa.h>
  18#include "rsapubkey.asn1.h"
  19#include "rsaprivkey.asn1.h"
  20
  21int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
  22              const void *value, size_t vlen)
  23{
  24        struct rsa_key *key = context;
  25        const u8 *ptr = value;
  26        size_t n_sz = vlen;
  27
  28        /* invalid key provided */
  29        if (!value || !vlen)
  30                return -EINVAL;
  31
  32        if (fips_enabled) {
  33                while (n_sz && !*ptr) {
  34                        ptr++;
  35                        n_sz--;
  36                }
  37
  38                /* In FIPS mode only allow key size 2K and higher */
  39                if (n_sz < 256) {
  40                        pr_err("RSA: key size not allowed in FIPS mode\n");
  41                        return -EINVAL;
  42                }
  43        }
  44
  45        key->n = value;
  46        key->n_sz = vlen;
  47
  48        return 0;
  49}
  50
  51int rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
  52              const void *value, size_t vlen)
  53{
  54        struct rsa_key *key = context;
  55
  56        /* invalid key provided */
  57        if (!value || !key->n_sz || !vlen || vlen > key->n_sz)
  58                return -EINVAL;
  59
  60        key->e = value;
  61        key->e_sz = vlen;
  62
  63        return 0;
  64}
  65
  66int rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
  67              const void *value, size_t vlen)
  68{
  69        struct rsa_key *key = context;
  70
  71        /* invalid key provided */
  72        if (!value || !key->n_sz || !vlen || vlen > key->n_sz)
  73                return -EINVAL;
  74
  75        key->d = value;
  76        key->d_sz = vlen;
  77
  78        return 0;
  79}
  80
  81int rsa_get_p(void *context, size_t hdrlen, unsigned char tag,
  82              const void *value, size_t vlen)
  83{
  84        struct rsa_key *key = context;
  85
  86        /* invalid key provided */
  87        if (!value || !vlen || vlen > key->n_sz)
  88                return -EINVAL;
  89
  90        key->p = value;
  91        key->p_sz = vlen;
  92
  93        return 0;
  94}
  95
  96int rsa_get_q(void *context, size_t hdrlen, unsigned char tag,
  97              const void *value, size_t vlen)
  98{
  99        struct rsa_key *key = context;
 100
 101        /* invalid key provided */
 102        if (!value || !vlen || vlen > key->n_sz)
 103                return -EINVAL;
 104
 105        key->q = value;
 106        key->q_sz = vlen;
 107
 108        return 0;
 109}
 110
 111int rsa_get_dp(void *context, size_t hdrlen, unsigned char tag,
 112               const void *value, size_t vlen)
 113{
 114        struct rsa_key *key = context;
 115
 116        /* invalid key provided */
 117        if (!value || !vlen || vlen > key->n_sz)
 118                return -EINVAL;
 119
 120        key->dp = value;
 121        key->dp_sz = vlen;
 122
 123        return 0;
 124}
 125
 126int rsa_get_dq(void *context, size_t hdrlen, unsigned char tag,
 127               const void *value, size_t vlen)
 128{
 129        struct rsa_key *key = context;
 130
 131        /* invalid key provided */
 132        if (!value || !vlen || vlen > key->n_sz)
 133                return -EINVAL;
 134
 135        key->dq = value;
 136        key->dq_sz = vlen;
 137
 138        return 0;
 139}
 140
 141int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag,
 142                 const void *value, size_t vlen)
 143{
 144        struct rsa_key *key = context;
 145
 146        /* invalid key provided */
 147        if (!value || !vlen || vlen > key->n_sz)
 148                return -EINVAL;
 149
 150        key->qinv = value;
 151        key->qinv_sz = vlen;
 152
 153        return 0;
 154}
 155
 156/**
 157 * rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
 158 *                       provided struct rsa_key, pointers to the raw key as is,
 159 *                       so that the caller can copy it or MPI parse it, etc.
 160 *
 161 * @rsa_key:    struct rsa_key key representation
 162 * @key:        key in BER format
 163 * @key_len:    length of key
 164 *
 165 * Return:      0 on success or error code in case of error
 166 */
 167int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
 168                      unsigned int key_len)
 169{
 170        return asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
 171}
 172EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
 173
 174/**
 175 * rsa_parse_priv_key() - decodes the BER encoded buffer and stores in the
 176 *                        provided struct rsa_key, pointers to the raw key
 177 *                        as is, so that the caller can copy it or MPI parse it,
 178 *                        etc.
 179 *
 180 * @rsa_key:    struct rsa_key key representation
 181 * @key:        key in BER format
 182 * @key_len:    length of key
 183 *
 184 * Return:      0 on success or error code in case of error
 185 */
 186int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
 187                       unsigned int key_len)
 188{
 189        return asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
 190}
 191EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
 192