]>
Commit | Line | Data |
---|---|---|
cfc2bb32 TS |
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 "rsakey-asn1.h" | |
19 | ||
20 | int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, | |
21 | const void *value, size_t vlen) | |
22 | { | |
23 | struct rsa_key *key = context; | |
24 | ||
25 | key->n = mpi_read_raw_data(value, vlen); | |
26 | ||
27 | if (!key->n) | |
28 | return -ENOMEM; | |
29 | ||
30 | /* In FIPS mode only allow key size 2K & 3K */ | |
31 | if (fips_enabled && (mpi_get_size(key->n) != 256 || | |
32 | mpi_get_size(key->n) != 384)) { | |
33 | pr_err("RSA: key size not allowed in FIPS mode\n"); | |
34 | mpi_free(key->n); | |
35 | key->n = NULL; | |
36 | return -EINVAL; | |
37 | } | |
38 | return 0; | |
39 | } | |
40 | ||
41 | int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, | |
42 | const void *value, size_t vlen) | |
43 | { | |
44 | struct rsa_key *key = context; | |
45 | ||
46 | key->e = mpi_read_raw_data(value, vlen); | |
47 | ||
48 | if (!key->e) | |
49 | return -ENOMEM; | |
50 | ||
51 | return 0; | |
52 | } | |
53 | ||
54 | int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, | |
55 | const void *value, size_t vlen) | |
56 | { | |
57 | struct rsa_key *key = context; | |
58 | ||
59 | key->d = mpi_read_raw_data(value, vlen); | |
60 | ||
61 | if (!key->d) | |
62 | return -ENOMEM; | |
63 | ||
64 | /* In FIPS mode only allow key size 2K & 3K */ | |
65 | if (fips_enabled && (mpi_get_size(key->d) != 256 || | |
66 | mpi_get_size(key->d) != 384)) { | |
67 | pr_err("RSA: key size not allowed in FIPS mode\n"); | |
68 | mpi_free(key->d); | |
69 | key->d = NULL; | |
70 | return -EINVAL; | |
71 | } | |
72 | return 0; | |
73 | } | |
74 | ||
75 | static void free_mpis(struct rsa_key *key) | |
76 | { | |
77 | mpi_free(key->n); | |
78 | mpi_free(key->e); | |
79 | mpi_free(key->d); | |
80 | key->n = NULL; | |
81 | key->e = NULL; | |
82 | key->d = NULL; | |
83 | } | |
84 | ||
85 | /** | |
86 | * rsa_free_key() - frees rsa key allocated by rsa_parse_key() | |
87 | * | |
88 | * @rsa_key: struct rsa_key key representation | |
89 | */ | |
90 | void rsa_free_key(struct rsa_key *key) | |
91 | { | |
92 | free_mpis(key); | |
93 | } | |
94 | EXPORT_SYMBOL_GPL(rsa_free_key); | |
95 | ||
96 | /** | |
97 | * rsa_parse_key() - extracts an rsa key from BER encoded buffer | |
98 | * and stores it in the provided struct rsa_key | |
99 | * | |
100 | * @rsa_key: struct rsa_key key representation | |
101 | * @key: key in BER format | |
102 | * @key_len: length of key | |
103 | * | |
104 | * Return: 0 on success or error code in case of error | |
105 | */ | |
106 | int rsa_parse_key(struct rsa_key *rsa_key, const void *key, | |
107 | unsigned int key_len) | |
108 | { | |
109 | int ret; | |
110 | ||
111 | free_mpis(rsa_key); | |
112 | ret = asn1_ber_decoder(&rsakey_decoder, rsa_key, key, key_len); | |
113 | if (ret < 0) | |
114 | goto error; | |
115 | ||
116 | return 0; | |
117 | error: | |
118 | free_mpis(rsa_key); | |
119 | return ret; | |
120 | } | |
121 | EXPORT_SYMBOL_GPL(rsa_parse_key); |