1 /* In-software asymmetric public-key crypto subtype 2 * 3 * See Documentation/crypto/asymmetric-keys.txt 4 * 5 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 6 * Written by David Howells (dhowells@redhat.com) 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public Licence 10 * as published by the Free Software Foundation; either version 11 * 2 of the Licence, or (at your option) any later version. 12 */ 13 14 #define pr_fmt(fmt) "PKEY: "fmt 15 #include <linux/module.h> 16 #include <linux/export.h> 17 #include <linux/kernel.h> 18 #include <linux/slab.h> 19 #include <linux/seq_file.h> 20 #include <linux/scatterlist.h> 21 #include <keys/asymmetric-subtype.h> 22 #include <crypto/public_key.h> 23 #include <crypto/akcipher.h> 24 25 MODULE_LICENSE("GPL"); 26 27 /* 28 * Provide a part of a description of the key for /proc/keys. 29 */ 30 static void public_key_describe(const struct key *asymmetric_key, 31 struct seq_file *m) 32 { 33 struct public_key *key = asymmetric_key->payload.data[asym_crypto]; 34 35 if (key) 36 seq_printf(m, "%s.%s", key->id_type, key->pkey_algo); 37 } 38 39 /* 40 * Destroy a public key algorithm key. 41 */ 42 void public_key_free(struct public_key *key) 43 { 44 if (key) { 45 kfree(key->key); 46 kfree(key); 47 } 48 } 49 EXPORT_SYMBOL_GPL(public_key_free); 50 51 /* 52 * Destroy a public key algorithm key. 53 */ 54 static void public_key_destroy(void *payload0, void *payload3) 55 { 56 public_key_free(payload0); 57 public_key_signature_free(payload3); 58 } 59 60 /* 61 * Verify a signature using a public key. 62 */ 63 int public_key_verify_signature(const struct public_key *pkey, 64 const struct public_key_signature *sig) 65 { 66 struct crypto_wait cwait; 67 struct crypto_akcipher *tfm; 68 struct akcipher_request *req; 69 struct scatterlist sig_sg, digest_sg; 70 const char *alg_name; 71 char alg_name_buf[CRYPTO_MAX_ALG_NAME]; 72 void *output; 73 unsigned int outlen; 74 int ret = -ENOMEM; 75 76 pr_devel("==>%s()\n", __func__); 77 78 BUG_ON(!pkey); 79 BUG_ON(!sig); 80 BUG_ON(!sig->digest); 81 BUG_ON(!sig->s); 82 83 alg_name = sig->pkey_algo; 84 if (strcmp(sig->pkey_algo, "rsa") == 0) { 85 /* The data wangled by the RSA algorithm is typically padded 86 * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 87 * sec 8.2]. 88 */ 89 if (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME, 90 "pkcs1pad(rsa,%s)", sig->hash_algo 91 ) >= CRYPTO_MAX_ALG_NAME) 92 return -EINVAL; 93 alg_name = alg_name_buf; 94 } 95 96 tfm = crypto_alloc_akcipher(alg_name, 0, 0); 97 if (IS_ERR(tfm)) 98 return PTR_ERR(tfm); 99 100 req = akcipher_request_alloc(tfm, GFP_KERNEL); 101 if (!req) 102 goto error_free_tfm; 103 104 ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); 105 if (ret) 106 goto error_free_req; 107 108 ret = -ENOMEM; 109 outlen = crypto_akcipher_maxsize(tfm); 110 output = kmalloc(outlen, GFP_KERNEL); 111 if (!output) 112 goto error_free_req; 113 114 sg_init_one(&sig_sg, sig->s, sig->s_size); 115 sg_init_one(&digest_sg, output, outlen); 116 akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig->s_size, 117 outlen); 118 crypto_init_wait(&cwait); 119 akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | 120 CRYPTO_TFM_REQ_MAY_SLEEP, 121 crypto_req_done, &cwait); 122 123 /* Perform the verification calculation. This doesn't actually do the 124 * verification, but rather calculates the hash expected by the 125 * signature and returns that to us. 126 */ 127 ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait); 128 if (ret < 0) 129 goto out_free_output; 130 131 /* Do the actual verification step. */ 132 if (req->dst_len != sig->digest_size || 133 memcmp(sig->digest, output, sig->digest_size) != 0) 134 ret = -EKEYREJECTED; 135 136 out_free_output: 137 kfree(output); 138 error_free_req: 139 akcipher_request_free(req); 140 error_free_tfm: 141 crypto_free_akcipher(tfm); 142 pr_devel("<==%s() = %d\n", __func__, ret); 143 return ret; 144 } 145 EXPORT_SYMBOL_GPL(public_key_verify_signature); 146 147 static int public_key_verify_signature_2(const struct key *key, 148 const struct public_key_signature *sig) 149 { 150 const struct public_key *pk = key->payload.data[asym_crypto]; 151 return public_key_verify_signature(pk, sig); 152 } 153 154 /* 155 * Public key algorithm asymmetric key subtype 156 */ 157 struct asymmetric_key_subtype public_key_subtype = { 158 .owner = THIS_MODULE, 159 .name = "public_key", 160 .name_len = sizeof("public_key") - 1, 161 .describe = public_key_describe, 162 .destroy = public_key_destroy, 163 .verify_signature = public_key_verify_signature_2, 164 }; 165 EXPORT_SYMBOL_GPL(public_key_subtype); 166