forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KEYS: Asymmetric public-key algorithm crypto key subtype
Add a subtype for supporting asymmetric public-key encryption algorithms such as DSA (FIPS-186) and RSA (PKCS#1 / RFC1337). Signed-off-by: David Howells <[email protected]> Signed-off-by: Rusty Russell <[email protected]>
- Loading branch information
1 parent
46c6f17
commit a9681bf
Showing
5 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* In-software asymmetric public-key crypto subtype | ||
* | ||
* See Documentation/crypto/asymmetric-keys.txt | ||
* | ||
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
* Written by David Howells ([email protected]) | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public Licence | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the Licence, or (at your option) any later version. | ||
*/ | ||
|
||
#define pr_fmt(fmt) "PKEY: "fmt | ||
#include <linux/module.h> | ||
#include <linux/export.h> | ||
#include <linux/kernel.h> | ||
#include <linux/slab.h> | ||
#include <linux/seq_file.h> | ||
#include <keys/asymmetric-subtype.h> | ||
#include "public_key.h" | ||
|
||
MODULE_LICENSE("GPL"); | ||
|
||
const char *const pkey_algo[PKEY_ALGO__LAST] = { | ||
[PKEY_ALGO_DSA] = "DSA", | ||
[PKEY_ALGO_RSA] = "RSA", | ||
}; | ||
EXPORT_SYMBOL_GPL(pkey_algo); | ||
|
||
const char *const pkey_hash_algo[PKEY_HASH__LAST] = { | ||
[PKEY_HASH_MD4] = "md4", | ||
[PKEY_HASH_MD5] = "md5", | ||
[PKEY_HASH_SHA1] = "sha1", | ||
[PKEY_HASH_RIPE_MD_160] = "rmd160", | ||
[PKEY_HASH_SHA256] = "sha256", | ||
[PKEY_HASH_SHA384] = "sha384", | ||
[PKEY_HASH_SHA512] = "sha512", | ||
[PKEY_HASH_SHA224] = "sha224", | ||
}; | ||
EXPORT_SYMBOL_GPL(pkey_hash_algo); | ||
|
||
const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = { | ||
[PKEY_ID_PGP] = "PGP", | ||
[PKEY_ID_X509] = "X509", | ||
}; | ||
EXPORT_SYMBOL_GPL(pkey_id_type); | ||
|
||
/* | ||
* Provide a part of a description of the key for /proc/keys. | ||
*/ | ||
static void public_key_describe(const struct key *asymmetric_key, | ||
struct seq_file *m) | ||
{ | ||
struct public_key *key = asymmetric_key->payload.data; | ||
|
||
if (key) | ||
seq_printf(m, "%s.%s", | ||
pkey_id_type[key->id_type], key->algo->name); | ||
} | ||
|
||
/* | ||
* Destroy a public key algorithm key. | ||
*/ | ||
void public_key_destroy(void *payload) | ||
{ | ||
struct public_key *key = payload; | ||
int i; | ||
|
||
if (key) { | ||
for (i = 0; i < ARRAY_SIZE(key->mpi); i++) | ||
mpi_free(key->mpi[i]); | ||
kfree(key); | ||
} | ||
} | ||
EXPORT_SYMBOL_GPL(public_key_destroy); | ||
|
||
/* | ||
* Verify a signature using a public key. | ||
*/ | ||
static int public_key_verify_signature(const struct key *key, | ||
const struct public_key_signature *sig) | ||
{ | ||
const struct public_key *pk = key->payload.data; | ||
|
||
if (!pk->algo->verify_signature) | ||
return -ENOTSUPP; | ||
|
||
if (sig->nr_mpi != pk->algo->n_sig_mpi) { | ||
pr_debug("Signature has %u MPI not %u\n", | ||
sig->nr_mpi, pk->algo->n_sig_mpi); | ||
return -EINVAL; | ||
} | ||
|
||
return pk->algo->verify_signature(pk, sig); | ||
} | ||
|
||
/* | ||
* Public key algorithm asymmetric key subtype | ||
*/ | ||
struct asymmetric_key_subtype public_key_subtype = { | ||
.owner = THIS_MODULE, | ||
.name = "public_key", | ||
.describe = public_key_describe, | ||
.destroy = public_key_destroy, | ||
.verify_signature = public_key_verify_signature, | ||
}; | ||
EXPORT_SYMBOL_GPL(public_key_subtype); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* Public key algorithm internals | ||
* | ||
* See Documentation/crypto/asymmetric-keys.txt | ||
* | ||
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
* Written by David Howells ([email protected]) | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public Licence | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the Licence, or (at your option) any later version. | ||
*/ | ||
|
||
#include <crypto/public_key.h> | ||
|
||
extern struct asymmetric_key_subtype public_key_subtype; | ||
|
||
/* | ||
* Public key algorithm definition. | ||
*/ | ||
struct public_key_algorithm { | ||
const char *name; | ||
u8 n_pub_mpi; /* Number of MPIs in public key */ | ||
u8 n_sec_mpi; /* Number of MPIs in secret key */ | ||
u8 n_sig_mpi; /* Number of MPIs in a signature */ | ||
int (*verify_signature)(const struct public_key *key, | ||
const struct public_key_signature *sig); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* Asymmetric public-key algorithm definitions | ||
* | ||
* See Documentation/crypto/asymmetric-keys.txt | ||
* | ||
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
* Written by David Howells ([email protected]) | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public Licence | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the Licence, or (at your option) any later version. | ||
*/ | ||
|
||
#ifndef _LINUX_PUBLIC_KEY_H | ||
#define _LINUX_PUBLIC_KEY_H | ||
|
||
#include <linux/mpi.h> | ||
|
||
enum pkey_algo { | ||
PKEY_ALGO_DSA, | ||
PKEY_ALGO_RSA, | ||
PKEY_ALGO__LAST | ||
}; | ||
|
||
extern const char *const pkey_algo[PKEY_ALGO__LAST]; | ||
|
||
enum pkey_hash_algo { | ||
PKEY_HASH_MD4, | ||
PKEY_HASH_MD5, | ||
PKEY_HASH_SHA1, | ||
PKEY_HASH_RIPE_MD_160, | ||
PKEY_HASH_SHA256, | ||
PKEY_HASH_SHA384, | ||
PKEY_HASH_SHA512, | ||
PKEY_HASH_SHA224, | ||
PKEY_HASH__LAST | ||
}; | ||
|
||
extern const char *const pkey_hash_algo[PKEY_HASH__LAST]; | ||
|
||
enum pkey_id_type { | ||
PKEY_ID_PGP, /* OpenPGP generated key ID */ | ||
PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ | ||
PKEY_ID_TYPE__LAST | ||
}; | ||
|
||
extern const char *const pkey_id_type[PKEY_ID_TYPE__LAST]; | ||
|
||
/* | ||
* Cryptographic data for the public-key subtype of the asymmetric key type. | ||
* | ||
* Note that this may include private part of the key as well as the public | ||
* part. | ||
*/ | ||
struct public_key { | ||
const struct public_key_algorithm *algo; | ||
u8 capabilities; | ||
#define PKEY_CAN_ENCRYPT 0x01 | ||
#define PKEY_CAN_DECRYPT 0x02 | ||
#define PKEY_CAN_SIGN 0x04 | ||
#define PKEY_CAN_VERIFY 0x08 | ||
enum pkey_id_type id_type : 8; | ||
union { | ||
MPI mpi[5]; | ||
struct { | ||
MPI p; /* DSA prime */ | ||
MPI q; /* DSA group order */ | ||
MPI g; /* DSA group generator */ | ||
MPI y; /* DSA public-key value = g^x mod p */ | ||
MPI x; /* DSA secret exponent (if present) */ | ||
} dsa; | ||
struct { | ||
MPI n; /* RSA public modulus */ | ||
MPI e; /* RSA public encryption exponent */ | ||
MPI d; /* RSA secret encryption exponent (if present) */ | ||
MPI p; /* RSA secret prime (if present) */ | ||
MPI q; /* RSA secret prime (if present) */ | ||
} rsa; | ||
}; | ||
}; | ||
|
||
extern void public_key_destroy(void *payload); | ||
|
||
/* | ||
* Public key cryptography signature data | ||
*/ | ||
struct public_key_signature { | ||
u8 *digest; | ||
u8 digest_size; /* Number of bytes in digest */ | ||
u8 nr_mpi; /* Occupancy of mpi[] */ | ||
enum pkey_hash_algo pkey_hash_algo : 8; | ||
union { | ||
MPI mpi[2]; | ||
struct { | ||
MPI s; /* m^d mod n */ | ||
} rsa; | ||
struct { | ||
MPI r; | ||
MPI s; | ||
} dsa; | ||
}; | ||
}; | ||
|
||
#endif /* _LINUX_PUBLIC_KEY_H */ |