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
  26        key->n = mpi_read_raw_data(value, vlen);
  27
  28        if (!key->n)
  29                return -ENOMEM;
  30
  31        /* In FIPS mode only allow key size 2K & 3K */
  32        if (fips_enabled && (mpi_get_size(key->n) != 256 &&
  33                             mpi_get_size(key->n) != 384)) {
  34                pr_err("RSA: key size not allowed in FIPS mode\n");
  35                mpi_free(key->n);
  36                key->n = NULL;
  37                return -EINVAL;
  38        }
  39        return 0;
  40}
  41
  42int rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
  43              const void *value, size_t vlen)
  44{
  45        struct rsa_key *key = context;
  46
  47        key->e = mpi_read_raw_data(value, vlen);
  48
  49        if (!key->e)
  50                return -ENOMEM;
  51
  52        return 0;
  53}
  54
  55int rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
  56              const void *value, size_t vlen)
  57{
  58        struct rsa_key *key = context;
  59
  60        key->d = mpi_read_raw_data(value, vlen);
  61
  62        if (!key->d)
  63                return -ENOMEM;
  64
  65        /* In FIPS mode only allow key size 2K & 3K */
  66        if (fips_enabled && (mpi_get_size(key->d) != 256 &&
  67                             mpi_get_size(key->d) != 384)) {
  68                pr_err("RSA: key size not allowed in FIPS mode\n");
  69                mpi_free(key->d);
  70                key->d = NULL;
  71                return -EINVAL;
  72        }
  73        return 0;
  74}
  75
  76static void free_mpis(struct rsa_key *key)
  77{
  78        mpi_free(key->n);
  79        mpi_free(key->e);
  80        mpi_free(key->d);
  81        key->n = NULL;
  82        key->e = NULL;
  83        key->d = NULL;
  84}
  85
  86/**
  87 * rsa_free_key() - frees rsa key allocated by rsa_parse_key()
  88 *
  89 * @rsa_key:    struct rsa_key key representation
  90 */
  91void rsa_free_key(struct rsa_key *key)
  92{
  93        free_mpis(key);
  94}
  95EXPORT_SYMBOL_GPL(rsa_free_key);
  96
  97/**
  98 * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer
  99 *                       and stores it in the provided struct rsa_key
 100 *
 101 * @rsa_key:    struct rsa_key key representation
 102 * @key:        key in BER format
 103 * @key_len:    length of key
 104 *
 105 * Return:      0 on success or error code in case of error
 106 */
 107int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
 108                      unsigned int key_len)
 109{
 110        int ret;
 111
 112        free_mpis(rsa_key);
 113        ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
 114        if (ret < 0)
 115                goto error;
 116
 117        return 0;
 118error:
 119        free_mpis(rsa_key);
 120        return ret;
 121}
 122EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
 123
 124/**
 125 * rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer
 126 *                       and stores it in the provided struct rsa_key
 127 *
 128 * @rsa_key:    struct rsa_key key representation
 129 * @key:        key in BER format
 130 * @key_len:    length of key
 131 *
 132 * Return:      0 on success or error code in case of error
 133 */
 134int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
 135                       unsigned int key_len)
 136{
 137        int ret;
 138
 139        free_mpis(rsa_key);
 140        ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
 141        if (ret < 0)
 142                goto error;
 143
 144        return 0;
 145error:
 146        free_mpis(rsa_key);
 147        return ret;
 148}
 149EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
 150