diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-26 08:51:23 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-26 08:51:23 -0700 |
| commit | a4a78bc8ead44c3cdb470c6e1f37afcabdddfc14 (patch) | |
| tree | b86bd2a304d056b23a85bb34c79e033af7ab1b0f /crypto | |
| parent | ffc766b31e900e91454d53b8619f0ff5377df945 (diff) | |
| parent | e3a606f2c544b231f6079c8c5fea451e772e1139 (diff) | |
| download | linux-a4a78bc8ead44c3cdb470c6e1f37afcabdddfc14.tar.gz linux-a4a78bc8ead44c3cdb470c6e1f37afcabdddfc14.tar.bz2 linux-a4a78bc8ead44c3cdb470c6e1f37afcabdddfc14.zip | |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
"API:
- crypto_destroy_tfm now ignores errors as well as NULL pointers
Algorithms:
- Add explicit curve IDs in ECDH algorithm names
- Add NIST P384 curve parameters
- Add ECDSA
Drivers:
- Add support for Green Sardine in ccp
- Add ecdh/curve25519 to hisilicon/hpre
- Add support for AM64 in sa2ul"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (184 commits)
fsverity: relax build time dependency on CRYPTO_SHA256
fscrypt: relax Kconfig dependencies for crypto API algorithms
crypto: camellia - drop duplicate "depends on CRYPTO"
crypto: s5p-sss - consistently use local 'dev' variable in probe()
crypto: s5p-sss - remove unneeded local variable initialization
crypto: s5p-sss - simplify getting of_device_id match data
ccp: ccp - add support for Green Sardine
crypto: ccp - Make ccp_dev_suspend and ccp_dev_resume void functions
crypto: octeontx2 - add support for OcteonTX2 98xx CPT block.
crypto: chelsio/chcr - Remove useless MODULE_VERSION
crypto: ux500/cryp - Remove duplicate argument
crypto: chelsio - remove unused function
crypto: sa2ul - Add support for AM64
crypto: sa2ul - Support for per channel coherency
dt-bindings: crypto: ti,sa2ul: Add new compatible for AM64
crypto: hisilicon - enable new error types for QM
crypto: hisilicon - add new error type for SEC
crypto: hisilicon - support new error types for ZIP
crypto: hisilicon - dynamic configuration 'err_info'
crypto: doc - fix kernel-doc notation in chacha.c and af_alg.c
...
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/Kconfig | 15 | ||||
| -rw-r--r-- | crypto/Makefile | 6 | ||||
| -rw-r--r-- | crypto/aegis.h | 19 | ||||
| -rw-r--r-- | crypto/aegis128-core.c | 15 | ||||
| -rw-r--r-- | crypto/aegis128-neon.c | 10 | ||||
| -rw-r--r-- | crypto/af_alg.c | 94 | ||||
| -rw-r--r-- | crypto/api.c | 2 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/public_key.c | 4 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/x509_cert_parser.c | 49 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/x509_public_key.c | 4 | ||||
| -rw-r--r-- | crypto/crc32_generic.c | 24 | ||||
| -rw-r--r-- | crypto/ecc.c | 291 | ||||
| -rw-r--r-- | crypto/ecc.h | 49 | ||||
| -rw-r--r-- | crypto/ecc_curve_defs.h | 49 | ||||
| -rw-r--r-- | crypto/ecdh.c | 72 | ||||
| -rw-r--r-- | crypto/ecdh_helper.c | 4 | ||||
| -rw-r--r-- | crypto/ecdsa.c | 376 | ||||
| -rw-r--r-- | crypto/ecdsasignature.asn1 | 4 | ||||
| -rw-r--r-- | crypto/fcrypt.c | 5 | ||||
| -rw-r--r-- | crypto/jitterentropy.c | 8 | ||||
| -rw-r--r-- | crypto/keywrap.c | 4 | ||||
| -rw-r--r-- | crypto/rng.c | 10 | ||||
| -rw-r--r-- | crypto/serpent_generic.c | 39 | ||||
| -rw-r--r-- | crypto/testmgr.c | 42 | ||||
| -rw-r--r-- | crypto/testmgr.h | 458 |
25 files changed, 1356 insertions, 297 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 5809cc198fa7..ca3b02dcbbfa 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -242,6 +242,16 @@ config CRYPTO_ECDH help Generic implementation of the ECDH algorithm +config CRYPTO_ECDSA + tristate "ECDSA (NIST P192, P256 etc.) algorithm" + select CRYPTO_ECC + select CRYPTO_AKCIPHER + select ASN1 + help + Elliptic Curve Digital Signature Algorithm (NIST P192, P256 etc.) + is A NIST cryptographic standard algorithm. Only signature verification + is implemented. + config CRYPTO_ECRDSA tristate "EC-RDSA (GOST 34.10) algorithm" select CRYPTO_ECC @@ -1213,7 +1223,6 @@ config CRYPTO_BLOWFISH_X86_64 config CRYPTO_CAMELLIA tristate "Camellia cipher algorithms" - depends on CRYPTO select CRYPTO_ALGAPI help Camellia cipher algorithms module. @@ -1229,7 +1238,6 @@ config CRYPTO_CAMELLIA config CRYPTO_CAMELLIA_X86_64 tristate "Camellia cipher algorithm (x86_64)" depends on X86 && 64BIT - depends on CRYPTO select CRYPTO_SKCIPHER imply CRYPTO_CTR help @@ -1246,7 +1254,6 @@ config CRYPTO_CAMELLIA_X86_64 config CRYPTO_CAMELLIA_AESNI_AVX_X86_64 tristate "Camellia cipher algorithm (x86_64/AES-NI/AVX)" depends on X86 && 64BIT - depends on CRYPTO select CRYPTO_SKCIPHER select CRYPTO_CAMELLIA_X86_64 select CRYPTO_SIMD @@ -1265,7 +1272,6 @@ config CRYPTO_CAMELLIA_AESNI_AVX_X86_64 config CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 tristate "Camellia cipher algorithm (x86_64/AES-NI/AVX2)" depends on X86 && 64BIT - depends on CRYPTO select CRYPTO_CAMELLIA_AESNI_AVX_X86_64 help Camellia cipher algorithm module (x86_64/AES-NI/AVX2). @@ -1281,7 +1287,6 @@ config CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 config CRYPTO_CAMELLIA_SPARC64 tristate "Camellia cipher algorithm (SPARC64)" depends on SPARC64 - depends on CRYPTO select CRYPTO_ALGAPI select CRYPTO_SKCIPHER help diff --git a/crypto/Makefile b/crypto/Makefile index cf23affb1678..10526d4559b8 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -50,6 +50,12 @@ sm2_generic-y += sm2.o obj-$(CONFIG_CRYPTO_SM2) += sm2_generic.o +$(obj)/ecdsasignature.asn1.o: $(obj)/ecdsasignature.asn1.c $(obj)/ecdsasignature.asn1.h +$(obj)/ecdsa.o: $(obj)/ecdsasignature.asn1.h +ecdsa_generic-y += ecdsa.o +ecdsa_generic-y += ecdsasignature.asn1.o +obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o + crypto_acompress-y := acompress.o crypto_acompress-y += scompress.o obj-$(CONFIG_CRYPTO_ACOMP2) += crypto_acompress.o diff --git a/crypto/aegis.h b/crypto/aegis.h index 6920ebe77679..6ef9c174c973 100644 --- a/crypto/aegis.h +++ b/crypto/aegis.h @@ -21,9 +21,28 @@ union aegis_block { u8 bytes[AEGIS_BLOCK_SIZE]; }; +struct aegis_state; + +extern int aegis128_have_aes_insn; + #define AEGIS_BLOCK_ALIGN (__alignof__(union aegis_block)) #define AEGIS_ALIGNED(p) IS_ALIGNED((uintptr_t)p, AEGIS_BLOCK_ALIGN) +bool crypto_aegis128_have_simd(void); +void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg); +void crypto_aegis128_init_simd(struct aegis_state *state, + const union aegis_block *key, + const u8 *iv); +void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst, + const u8 *src, unsigned int size); +void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst, + const u8 *src, unsigned int size); +int crypto_aegis128_final_simd(struct aegis_state *state, + union aegis_block *tag_xor, + unsigned int assoclen, + unsigned int cryptlen, + unsigned int authsize); + static __always_inline void crypto_aegis_block_xor(union aegis_block *dst, const union aegis_block *src) { diff --git a/crypto/aegis128-core.c b/crypto/aegis128-core.c index 89dc1c559689..c4f1bfa1d04f 100644 --- a/crypto/aegis128-core.c +++ b/crypto/aegis128-core.c @@ -58,21 +58,6 @@ static bool aegis128_do_simd(void) return false; } -bool crypto_aegis128_have_simd(void); -void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg); -void crypto_aegis128_init_simd(struct aegis_state *state, - const union aegis_block *key, - const u8 *iv); -void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst, - const u8 *src, unsigned int size); -void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst, - const u8 *src, unsigned int size); -int crypto_aegis128_final_simd(struct aegis_state *state, - union aegis_block *tag_xor, - unsigned int assoclen, - unsigned int cryptlen, - unsigned int authsize); - static void crypto_aegis128_update(struct aegis_state *state) { union aegis_block tmp; diff --git a/crypto/aegis128-neon.c b/crypto/aegis128-neon.c index 94d591a002a4..a7856915ec85 100644 --- a/crypto/aegis128-neon.c +++ b/crypto/aegis128-neon.c @@ -30,7 +30,7 @@ bool crypto_aegis128_have_simd(void) return IS_ENABLED(CONFIG_ARM64); } -void crypto_aegis128_init_simd(union aegis_block *state, +void crypto_aegis128_init_simd(struct aegis_state *state, const union aegis_block *key, const u8 *iv) { @@ -39,14 +39,14 @@ void crypto_aegis128_init_simd(union aegis_block *state, kernel_neon_end(); } -void crypto_aegis128_update_simd(union aegis_block *state, const void *msg) +void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg) { kernel_neon_begin(); crypto_aegis128_update_neon(state, msg); kernel_neon_end(); } -void crypto_aegis128_encrypt_chunk_simd(union aegis_block *state, u8 *dst, +void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst, const u8 *src, unsigned int size) { kernel_neon_begin(); @@ -54,7 +54,7 @@ void crypto_aegis128_encrypt_chunk_simd(union aegis_block *state, u8 *dst, kernel_neon_end(); } -void crypto_aegis128_decrypt_chunk_simd(union aegis_block *state, u8 *dst, +void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst, const u8 *src, unsigned int size) { kernel_neon_begin(); @@ -62,7 +62,7 @@ void crypto_aegis128_decrypt_chunk_simd(union aegis_block *state, u8 *dst, kernel_neon_end(); } -int crypto_aegis128_final_simd(union aegis_block *state, +int crypto_aegis128_final_simd(struct aegis_state *state, union aegis_block *tag_xor, unsigned int assoclen, unsigned int cryptlen, diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 9acb9d2c4bcf..18cc82dc4a42 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -491,8 +491,8 @@ static int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) /** * af_alg_alloc_tsgl - allocate the TX SGL * - * @sk socket of connection to user space - * @return: 0 upon success, < 0 upon error + * @sk: socket of connection to user space + * Return: 0 upon success, < 0 upon error */ static int af_alg_alloc_tsgl(struct sock *sk) { @@ -525,15 +525,15 @@ static int af_alg_alloc_tsgl(struct sock *sk) } /** - * aead_count_tsgl - Count number of TX SG entries + * af_alg_count_tsgl - Count number of TX SG entries * * The counting starts from the beginning of the SGL to @bytes. If - * an offset is provided, the counting of the SG entries starts at the offset. + * an @offset is provided, the counting of the SG entries starts at the @offset. * - * @sk socket of connection to user space - * @bytes Count the number of SG entries holding given number of bytes. - * @offset Start the counting of SG entries from the given offset. - * @return Number of TX SG entries found given the constraints + * @sk: socket of connection to user space + * @bytes: Count the number of SG entries holding given number of bytes. + * @offset: Start the counting of SG entries from the given offset. + * Return: Number of TX SG entries found given the constraints */ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset) { @@ -577,19 +577,19 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset) EXPORT_SYMBOL_GPL(af_alg_count_tsgl); /** - * aead_pull_tsgl - Release the specified buffers from TX SGL + * af_alg_pull_tsgl - Release the specified buffers from TX SGL * - * If @dst is non-null, reassign the pages to dst. The caller must release + * If @dst is non-null, reassign the pages to @dst. The caller must release * the pages. If @dst_offset is given only reassign the pages to @dst starting * at the @dst_offset (byte). The caller must ensure that @dst is large * enough (e.g. by using af_alg_count_tsgl with the same offset). * - * @sk socket of connection to user space - * @used Number of bytes to pull from TX SGL - * @dst If non-NULL, buffer is reassigned to dst SGL instead of releasing. The - * caller must release the buffers in dst. - * @dst_offset Reassign the TX SGL from given offset. All buffers before - * reaching the offset is released. + * @sk: socket of connection to user space + * @used: Number of bytes to pull from TX SGL + * @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The + * caller must release the buffers in dst. + * @dst_offset: Reassign the TX SGL from given offset. All buffers before + * reaching the offset is released. */ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, size_t dst_offset) @@ -657,7 +657,7 @@ EXPORT_SYMBOL_GPL(af_alg_pull_tsgl); /** * af_alg_free_areq_sgls - Release TX and RX SGLs of the request * - * @areq Request holding the TX and RX SGL + * @areq: Request holding the TX and RX SGL */ static void af_alg_free_areq_sgls(struct af_alg_async_req *areq) { @@ -692,9 +692,9 @@ static void af_alg_free_areq_sgls(struct af_alg_async_req *areq) /** * af_alg_wait_for_wmem - wait for availability of writable memory * - * @sk socket of connection to user space - * @flags If MSG_DONTWAIT is set, then only report if function would sleep - * @return 0 when writable memory is available, < 0 upon error + * @sk: socket of connection to user space + * @flags: If MSG_DONTWAIT is set, then only report if function would sleep + * Return: 0 when writable memory is available, < 0 upon error */ static int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags) { @@ -725,7 +725,7 @@ static int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags) /** * af_alg_wmem_wakeup - wakeup caller when writable memory is available * - * @sk socket of connection to user space + * @sk: socket of connection to user space */ void af_alg_wmem_wakeup(struct sock *sk) { @@ -748,10 +748,10 @@ EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup); /** * af_alg_wait_for_data - wait for availability of TX data * - * @sk socket of connection to user space - * @flags If MSG_DONTWAIT is set, then only report if function would sleep - * @min Set to minimum request size if partial requests are allowed. - * @return 0 when writable memory is available, < 0 upon error + * @sk: socket of connection to user space + * @flags: If MSG_DONTWAIT is set, then only report if function would sleep + * @min: Set to minimum request size if partial requests are allowed. + * Return: 0 when writable memory is available, < 0 upon error */ int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min) { @@ -790,7 +790,7 @@ EXPORT_SYMBOL_GPL(af_alg_wait_for_data); /** * af_alg_data_wakeup - wakeup caller when new data can be sent to kernel * - * @sk socket of connection to user space + * @sk: socket of connection to user space */ static void af_alg_data_wakeup(struct sock *sk) { @@ -820,12 +820,12 @@ static void af_alg_data_wakeup(struct sock *sk) * * In addition, the ctx is filled with the information sent via CMSG. * - * @sock socket of connection to user space - * @msg message from user space - * @size size of message from user space - * @ivsize the size of the IV for the cipher operation to verify that the + * @sock: socket of connection to user space + * @msg: message from user space + * @size: size of message from user space + * @ivsize: the size of the IV for the cipher operation to verify that the * user-space-provided IV has the right size - * @return the number of copied data upon success, < 0 upon error + * Return: the number of copied data upon success, < 0 upon error */ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, unsigned int ivsize) @@ -977,6 +977,11 @@ EXPORT_SYMBOL_GPL(af_alg_sendmsg); /** * af_alg_sendpage - sendpage system call handler + * @sock: socket of connection to user space to write to + * @page: data to send + * @offset: offset into page to begin sending + * @size: length of data + * @flags: message send/receive flags * * This is a generic implementation of sendpage to fill ctx->tsgl_list. */ @@ -1035,6 +1040,7 @@ EXPORT_SYMBOL_GPL(af_alg_sendpage); /** * af_alg_free_resources - release resources required for crypto request + * @areq: Request holding the TX and RX SGL */ void af_alg_free_resources(struct af_alg_async_req *areq) { @@ -1047,6 +1053,9 @@ EXPORT_SYMBOL_GPL(af_alg_free_resources); /** * af_alg_async_cb - AIO callback handler + * @_req: async request info + * @err: if non-zero, error result to be returned via ki_complete(); + * otherwise return the AIO output length via ki_complete(). * * This handler cleans up the struct af_alg_async_req upon completion of the * AIO operation. @@ -1073,6 +1082,9 @@ EXPORT_SYMBOL_GPL(af_alg_async_cb); /** * af_alg_poll - poll system call handler + * @file: file pointer + * @sock: socket to poll + * @wait: poll_table */ __poll_t af_alg_poll(struct file *file, struct socket *sock, poll_table *wait) @@ -1098,9 +1110,9 @@ EXPORT_SYMBOL_GPL(af_alg_poll); /** * af_alg_alloc_areq - allocate struct af_alg_async_req * - * @sk socket of connection to user space - * @areqlen size of struct af_alg_async_req + crypto_*_reqsize - * @return allocated data structure or ERR_PTR upon error + * @sk: socket of connection to user space + * @areqlen: size of struct af_alg_async_req + crypto_*_reqsize + * Return: allocated data structure or ERR_PTR upon error */ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, unsigned int areqlen) @@ -1125,13 +1137,13 @@ EXPORT_SYMBOL_GPL(af_alg_alloc_areq); * af_alg_get_rsgl - create the RX SGL for the output data from the crypto * operation * - * @sk socket of connection to user space - * @msg user space message - * @flags flags used to invoke recvmsg with - * @areq instance of the cryptographic request that will hold the RX SGL - * @maxsize maximum number of bytes to be pulled from user space - * @outlen number of bytes in the RX SGL - * @return 0 on success, < 0 upon error + * @sk: socket of connection to user space + * @msg: user space message + * @flags: flags used to invoke recvmsg with + * @areq: instance of the cryptographic request that will hold the RX SGL + * @maxsize: maximum number of bytes to be pulled from user space + * @outlen: number of bytes in the RX SGL + * Return: 0 on success, < 0 upon error */ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, struct af_alg_async_req *areq, size_t maxsize, diff --git a/crypto/api.c b/crypto/api.c index ed08cbd5b9d3..c4eda56cff89 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -562,7 +562,7 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm) { struct crypto_alg *alg; - if (unlikely(!mem)) + if (IS_ERR_OR_NULL(mem)) return; alg = tfm->__crt_alg; diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 788a4ba1e2e7..4fefb219bfdc 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/seq_file.h> #include <linux/scatterlist.h> +#include <linux/asn1.h> #include <keys/asymmetric-subtype.h> #include <crypto/public_key.h> #include <crypto/akcipher.h> @@ -85,7 +86,8 @@ int software_key_determine_akcipher(const char *encoding, return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0; } - if (strcmp(encoding, "raw") == 0) { + if (strcmp(encoding, "raw") == 0 || + strcmp(encoding, "x962") == 0) { strcpy(alg_name, pkey->pkey_algo); return 0; } diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 52c9b455fc7d..6d003096b5bc 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -227,6 +227,26 @@ int x509_note_pkey_algo(void *context, size_t hdrlen, ctx->cert->sig->hash_algo = "sha224"; goto rsa_pkcs1; + case OID_id_ecdsa_with_sha1: + ctx->cert->sig->hash_algo = "sha1"; + goto ecdsa; + + case OID_id_ecdsa_with_sha224: + ctx->cert->sig->hash_algo = "sha224"; + goto ecdsa; + + case OID_id_ecdsa_with_sha256: + ctx->cert->sig->hash_algo = "sha256"; + goto ecdsa; + + case OID_id_ecdsa_with_sha384: + ctx->cert->sig->hash_algo = "sha384"; + goto ecdsa; + + case OID_id_ecdsa_with_sha512: + ctx->cert->sig->hash_algo = "sha512"; + goto ecdsa; + case OID_gost2012Signature256: ctx->cert->sig->hash_algo = "streebog256"; goto ecrdsa; @@ -255,6 +275,11 @@ sm2: ctx->cert->sig->encoding = "raw"; ctx->algo_oid = ctx->last_oid; return 0; +ecdsa: + ctx->cert->sig->pkey_algo = "ecdsa"; + ctx->cert->sig->encoding = "x962"; + ctx->algo_oid = ctx->last_oid; + return 0; } /* @@ -276,7 +301,8 @@ int x509_note_signature(void *context, size_t hdrlen, if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 || strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 || - strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0) { + strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0 || + strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0) { /* Discard the BIT STRING metadata */ if (vlen < 1 || *(const u8 *)value != 0) return -EBADMSG; @@ -459,6 +485,7 @@ int x509_extract_key_data(void *context, size_t hdrlen, const void *value, size_t vlen) { struct x509_parse_context *ctx = context; + enum OID oid; ctx->key_algo = ctx->last_oid; switch (ctx->last_oid) { @@ -470,7 +497,25 @@ int x509_extract_key_data(void *context, size_t hdrlen, ctx->cert->pub->pkey_algo = "ecrdsa"; break; case OID_id_ecPublicKey: - ctx->cert->pub->pkey_algo = "sm2"; + if (parse_OID(ctx->params, ctx->params_size, &oid) != 0) + return -EBADMSG; + + switch (oid) { + case OID_sm2: + ctx->cert->pub->pkey_algo = "sm2"; + break; + case OID_id_prime192v1: + ctx->cert->pub->pkey_algo = "ecdsa-nist-p192"; + break; + case OID_id_prime256v1: + ctx->cert->pub->pkey_algo = "ecdsa-nist-p256"; + break; + case OID_id_ansip384r1: + ctx->cert->pub->pkey_algo = "ecdsa-nist-p384"; + break; + default: + return -ENOPKG; + } break; default: return -ENOPKG; diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index ae450eb8be14..3d45161b271a 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -129,7 +129,9 @@ int x509_check_for_self_signed(struct x509_certificate *cert) } ret = -EKEYREJECTED; - if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0) + if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0 && + (strncmp(cert->pub->pkey_algo, "ecdsa-", 6) != 0 || + strcmp(cert->sig->pkey_algo, "ecdsa") != 0)) goto out; ret = public_key_verify_signature(cert->pub, cert->sig); diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c index 0e103fb5dd77..a989cb44fd16 100644 --- a/crypto/crc32_generic.c +++ b/crypto/crc32_generic.c @@ -1,26 +1,4 @@ -/* GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see http://www.gnu.org/licenses - * - * Please visit http://www.xyratex.com/contact if you need additional - * information or have any questions. - * - * GPL HEADER END - */ - +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2012 Xyratex Technology Limited */ diff --git a/crypto/ecc.c b/crypto/ecc.c index c80aa25994a0..afc6cefdc1d9 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <crypto/ecc_curve.h> #include <linux/module.h> #include <linux/random.h> #include <linux/slab.h> @@ -42,7 +43,14 @@ typedef struct { u64 m_high; } uint128_t; -static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id) +/* Returns curv25519 curve param */ +const struct ecc_curve *ecc_get_curve25519(void) +{ + return &ecc_25519; +} +EXPORT_SYMBOL(ecc_get_curve25519); + +const struct ecc_curve *ecc_get_curve(unsigned int curve_id) { switch (curve_id) { /* In FIPS mode only allow P256 and higher */ @@ -50,10 +58,13 @@ static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id) return fips_enabled ? NULL : &nist_p192; case ECC_CURVE_NIST_P256: return &nist_p256; + case ECC_CURVE_NIST_P384: + return &nist_p384; default: return NULL; } } +EXPORT_SYMBOL(ecc_get_curve); static u64 *ecc_alloc_digits_space(unsigned int ndigits) { @@ -128,7 +139,7 @@ bool vli_is_zero(const u64 *vli, unsigned int ndigits) } EXPORT_SYMBOL(vli_is_zero); -/* Returns nonzero if bit bit of vli is set. */ +/* Returns nonzero if bit of vli is set. */ static u64 vli_test_bit(const u64 *vli, unsigned int bit) { return (vli[bit / 64] & ((u64)1 << (bit % 64))); @@ -775,18 +786,133 @@ static void vli_mmod_fast_256(u64 *result, const u64 *product, } } +#define SL32OR32(x32, y32) (((u64)x32 << 32) | y32) +#define AND64H(x64) (x64 & 0xffFFffFF00000000ull) +#define AND64L(x64) (x64 & 0x00000000ffFFffFFull) + +/* Computes result = product % curve_prime + * from "Mathematical routines for the NIST prime elliptic curves" + */ +static void vli_mmod_fast_384(u64 *result, const u64 *product, + const u64 *curve_prime, u64 *tmp) +{ + int carry; + const unsigned int ndigits = 6; + + /* t */ + vli_set(result, product, ndigits); + + /* s1 */ + tmp[0] = 0; // 0 || 0 + tmp[1] = 0; // 0 || 0 + tmp[2] = SL32OR32(product[11], (product[10]>>32)); //a22||a21 + tmp[3] = product[11]>>32; // 0 ||a23 + tmp[4] = 0; // 0 || 0 + tmp[5] = 0; // 0 || 0 + carry = vli_lshift(tmp, tmp, 1, ndigits); + carry += vli_add(result, result, tmp, ndigits); + + /* s2 */ + tmp[0] = product[6]; //a13||a12 + tmp[1] = product[7]; //a15||a14 + tmp[2] = product[8]; //a17||a16 + tmp[3] = product[9]; //a19||a18 + tmp[4] = product[10]; //a21||a20 + tmp[5] = product[11]; //a23||a22 + carry += vli_add(result, result, tmp, ndigits); + + /* s3 */ + tmp[0] = SL32OR32(product[11], (product[10]>>32)); //a22||a21 + tmp[1] = SL32OR32(product[6], (product[11]>>32)); //a12||a23 + tmp[2] = SL32OR32(product[7], (product[6])>>32); //a14||a13 + tmp[3] = SL32OR32(product[8], (product[7]>>32)); //a16||a15 + tmp[4] = SL32OR32(product[9], (product[8]>>32)); //a18||a17 + tmp[5] = SL32OR32(product[10], (product[9]>>32)); //a20||a19 + carry += vli_add(result, result, tmp, ndigits); + + /* s4 */ + tmp[0] = AND64H(product[11]); //a23|| 0 + tmp[1] = (product[10]<<32); //a20|| 0 + tmp[2] = product[6]; //a13||a12 + tmp[3] = product[7]; //a15||a14 + tmp[4] = product[8]; //a17||a16 + tmp[5] = product[9]; //a19||a18 + carry += vli_add(result, result, tmp, ndigits); + + /* s5 */ + tmp[0] = 0; // 0|| 0 + tmp[1] = 0; // 0|| 0 + tmp[2] = product[10]; //a21||a20 + tmp[3] = product[11]; //a23||a22 + tmp[4] = 0; // 0|| 0 + tmp[5] = 0; // 0|| 0 + carry += vli_add(result, result, tmp, ndigits); + + /* s6 */ + tmp[0] = AND64L(product[10]); // 0 ||a20 + tmp[1] = AND64H(product[10]); //a21|| 0 + tmp[2] = product[11]; //a23||a22 + tmp[3] = 0; // 0 || 0 + tmp[4] = 0; // 0 || 0 + tmp[5] = 0; // 0 || 0 + carry += vli_add(result, result, tmp, ndigits); + + /* d1 */ + tmp[0] = SL32OR32(product[6], (product[11]>>32)); //a12||a23 + tmp[1] = SL32OR32(product[7], (product[6]>>32)); //a14||a13 + tmp[2] = SL32OR32(product[8], (product[7]>>32)); //a16||a15 + tmp[3] = SL32OR32(product[9], (product[8]>>32)); //a18||a17 + tmp[4] = SL32OR32(product[10], (product[9]>>32)); //a20||a19 + tmp[5] = SL32OR32(product[11], (product[10]>>32)); //a22||a21 + carry -= vli_sub(result, result, tmp, ndigits); + + /* d2 */ + tmp[0] = (product[10]<<32); //a20|| 0 + tmp[1] = SL32OR32(product[11], (product[10]>>32)); //a22||a21 + tmp[2] = (product[11]>>32); // 0 ||a23 + tmp[3] = 0; // 0 || 0 + tmp[4] = 0; // 0 || 0 + tmp[5] = 0; // 0 || 0 + carry -= vli_sub(result, result, tmp, ndigits); + + /* d3 */ + tmp[0] = 0; // 0 || 0 + tmp[1] = AND64H(product[11]); //a23|| 0 + tmp[2] = product[11]>>32; // 0 ||a23 + tmp[3] = 0; // 0 || 0 + tmp[4] = 0; // 0 || 0 + tmp[5] = 0; // 0 || 0 + carry -= vli_sub(result, result, tmp, ndigits); + + if (carry < 0) { + do { + carry += vli_add(result, result, curve_prime, ndigits); + } while (carry < 0); + } else { + while (carry || vli_cmp(curve_prime, result, ndigits) != 1) + carry -= vli_sub(result, result, curve_prime, ndigits); + } + +} + +#undef SL32OR32 +#undef AND64H +#undef AND64L + /* Computes result = product % curve_prime for different curve_primes. * * Note that curve_primes are distinguished just by heuristic check and * not by complete conformance check. */ static bool vli_mmod_fast(u64 *result, u64 *product, - const u64 *curve_prime, unsigned int ndigits) + const struct ecc_curve *curve) { u64 tmp[2 * ECC_MAX_DIGITS]; + const u64 *curve_prime = curve->p; |
