brintos

brintos / linux-shallow public Read only

0
0
Text · 13.3 KiB · 18a10ca Raw
432 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * Public Key Encryption4 *5 * Copyright (c) 2015, Intel Corporation6 * Authors: Tadeusz Struk <tadeusz.struk@intel.com>7 */8#ifndef _CRYPTO_AKCIPHER_H9#define _CRYPTO_AKCIPHER_H10 11#include <linux/atomic.h>12#include <linux/crypto.h>13 14/**15 * struct akcipher_request - public key request16 *17 * @base:	Common attributes for async crypto requests18 * @src:	Source data19 *		For verify op this is signature + digest, in that case20 *		total size of @src is @src_len + @dst_len.21 * @dst:	Destination data (Should be NULL for verify op)22 * @src_len:	Size of the input buffer23 *		For verify op it's size of signature part of @src, this part24 *		is supposed to be operated by cipher.25 * @dst_len:	Size of @dst buffer (for all ops except verify).26 *		It needs to be at least	as big as the expected result27 *		depending on the operation.28 *		After operation it will be updated with the actual size of the29 *		result.30 *		In case of error where the dst sgl size was insufficient,31 *		it will be updated to the size required for the operation.32 *		For verify op this is size of digest part in @src.33 * @__ctx:	Start of private context data34 */35struct akcipher_request {36	struct crypto_async_request base;37	struct scatterlist *src;38	struct scatterlist *dst;39	unsigned int src_len;40	unsigned int dst_len;41	void *__ctx[] CRYPTO_MINALIGN_ATTR;42};43 44/**45 * struct crypto_akcipher - user-instantiated objects which encapsulate46 * algorithms and core processing logic47 *48 * @reqsize:	Request context size required by algorithm implementation49 * @base:	Common crypto API algorithm data structure50 */51struct crypto_akcipher {52	unsigned int reqsize;53 54	struct crypto_tfm base;55};56 57/**58 * struct akcipher_alg - generic public key algorithm59 *60 * @sign:	Function performs a sign operation as defined by public key61 *		algorithm. In case of error, where the dst_len was insufficient,62 *		the req->dst_len will be updated to the size required for the63 *		operation64 * @verify:	Function performs a complete verify operation as defined by65 *		public key algorithm, returning verification status. Requires66 *		digest value as input parameter.67 * @encrypt:	Function performs an encrypt operation as defined by public key68 *		algorithm. In case of error, where the dst_len was insufficient,69 *		the req->dst_len will be updated to the size required for the70 *		operation71 * @decrypt:	Function performs a decrypt operation as defined by public key72 *		algorithm. In case of error, where the dst_len was insufficient,73 *		the req->dst_len will be updated to the size required for the74 *		operation75 * @set_pub_key: Function invokes the algorithm specific set public key76 *		function, which knows how to decode and interpret77 *		the BER encoded public key and parameters78 * @set_priv_key: Function invokes the algorithm specific set private key79 *		function, which knows how to decode and interpret80 *		the BER encoded private key and parameters81 * @max_size:	Function returns dest buffer size required for a given key.82 * @init:	Initialize the cryptographic transformation object.83 *		This function is used to initialize the cryptographic84 *		transformation object. This function is called only once at85 *		the instantiation time, right after the transformation context86 *		was allocated. In case the cryptographic hardware has some87 *		special requirements which need to be handled by software, this88 *		function shall check for the precise requirement of the89 *		transformation and put any software fallbacks in place.90 * @exit:	Deinitialize the cryptographic transformation object. This is a91 *		counterpart to @init, used to remove various changes set in92 *		@init.93 *94 * @base:	Common crypto API algorithm data structure95 */96struct akcipher_alg {97	int (*sign)(struct akcipher_request *req);98	int (*verify)(struct akcipher_request *req);99	int (*encrypt)(struct akcipher_request *req);100	int (*decrypt)(struct akcipher_request *req);101	int (*set_pub_key)(struct crypto_akcipher *tfm, const void *key,102			   unsigned int keylen);103	int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,104			    unsigned int keylen);105	unsigned int (*max_size)(struct crypto_akcipher *tfm);106	int (*init)(struct crypto_akcipher *tfm);107	void (*exit)(struct crypto_akcipher *tfm);108 109	struct crypto_alg base;110};111 112/**113 * DOC: Generic Public Key API114 *115 * The Public Key API is used with the algorithms of type116 * CRYPTO_ALG_TYPE_AKCIPHER (listed as type "akcipher" in /proc/crypto)117 */118 119/**120 * crypto_alloc_akcipher() - allocate AKCIPHER tfm handle121 * @alg_name: is the cra_name / name or cra_driver_name / driver name of the122 *	      public key algorithm e.g. "rsa"123 * @type: specifies the type of the algorithm124 * @mask: specifies the mask for the algorithm125 *126 * Allocate a handle for public key algorithm. The returned struct127 * crypto_akcipher is the handle that is required for any subsequent128 * API invocation for the public key operations.129 *130 * Return: allocated handle in case of success; IS_ERR() is true in case131 *	   of an error, PTR_ERR() returns the error code.132 */133struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,134					      u32 mask);135 136static inline struct crypto_tfm *crypto_akcipher_tfm(137	struct crypto_akcipher *tfm)138{139	return &tfm->base;140}141 142static inline struct akcipher_alg *__crypto_akcipher_alg(struct crypto_alg *alg)143{144	return container_of(alg, struct akcipher_alg, base);145}146 147static inline struct crypto_akcipher *__crypto_akcipher_tfm(148	struct crypto_tfm *tfm)149{150	return container_of(tfm, struct crypto_akcipher, base);151}152 153static inline struct akcipher_alg *crypto_akcipher_alg(154	struct crypto_akcipher *tfm)155{156	return __crypto_akcipher_alg(crypto_akcipher_tfm(tfm)->__crt_alg);157}158 159static inline unsigned int crypto_akcipher_reqsize(struct crypto_akcipher *tfm)160{161	return tfm->reqsize;162}163 164static inline void akcipher_request_set_tfm(struct akcipher_request *req,165					    struct crypto_akcipher *tfm)166{167	req->base.tfm = crypto_akcipher_tfm(tfm);168}169 170static inline struct crypto_akcipher *crypto_akcipher_reqtfm(171	struct akcipher_request *req)172{173	return __crypto_akcipher_tfm(req->base.tfm);174}175 176/**177 * crypto_free_akcipher() - free AKCIPHER tfm handle178 *179 * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()180 *181 * If @tfm is a NULL or error pointer, this function does nothing.182 */183static inline void crypto_free_akcipher(struct crypto_akcipher *tfm)184{185	crypto_destroy_tfm(tfm, crypto_akcipher_tfm(tfm));186}187 188/**189 * akcipher_request_alloc() - allocates public key request190 *191 * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()192 * @gfp:	allocation flags193 *194 * Return: allocated handle in case of success or NULL in case of an error.195 */196static inline struct akcipher_request *akcipher_request_alloc(197	struct crypto_akcipher *tfm, gfp_t gfp)198{199	struct akcipher_request *req;200 201	req = kmalloc(sizeof(*req) + crypto_akcipher_reqsize(tfm), gfp);202	if (likely(req))203		akcipher_request_set_tfm(req, tfm);204 205	return req;206}207 208/**209 * akcipher_request_free() - zeroize and free public key request210 *211 * @req:	request to free212 */213static inline void akcipher_request_free(struct akcipher_request *req)214{215	kfree_sensitive(req);216}217 218/**219 * akcipher_request_set_callback() - Sets an asynchronous callback.220 *221 * Callback will be called when an asynchronous operation on a given222 * request is finished.223 *224 * @req:	request that the callback will be set for225 * @flgs:	specify for instance if the operation may backlog226 * @cmpl:	callback which will be called227 * @data:	private data used by the caller228 */229static inline void akcipher_request_set_callback(struct akcipher_request *req,230						 u32 flgs,231						 crypto_completion_t cmpl,232						 void *data)233{234	req->base.complete = cmpl;235	req->base.data = data;236	req->base.flags = flgs;237}238 239/**240 * akcipher_request_set_crypt() - Sets request parameters241 *242 * Sets parameters required by crypto operation243 *244 * @req:	public key request245 * @src:	ptr to input scatter list246 * @dst:	ptr to output scatter list or NULL for verify op247 * @src_len:	size of the src input scatter list to be processed248 * @dst_len:	size of the dst output scatter list or size of signature249 *		portion in @src for verify op250 */251static inline void akcipher_request_set_crypt(struct akcipher_request *req,252					      struct scatterlist *src,253					      struct scatterlist *dst,254					      unsigned int src_len,255					      unsigned int dst_len)256{257	req->src = src;258	req->dst = dst;259	req->src_len = src_len;260	req->dst_len = dst_len;261}262 263/**264 * crypto_akcipher_maxsize() - Get len for output buffer265 *266 * Function returns the dest buffer size required for a given key.267 * Function assumes that the key is already set in the transformation. If this268 * function is called without a setkey or with a failed setkey, you will end up269 * in a NULL dereference.270 *271 * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()272 */273static inline unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)274{275	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);276 277	return alg->max_size(tfm);278}279 280/**281 * crypto_akcipher_encrypt() - Invoke public key encrypt operation282 *283 * Function invokes the specific public key encrypt operation for a given284 * public key algorithm285 *286 * @req:	asymmetric key request287 *288 * Return: zero on success; error code in case of error289 */290static inline int crypto_akcipher_encrypt(struct akcipher_request *req)291{292	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);293 294	return crypto_akcipher_alg(tfm)->encrypt(req);295}296 297/**298 * crypto_akcipher_decrypt() - Invoke public key decrypt operation299 *300 * Function invokes the specific public key decrypt operation for a given301 * public key algorithm302 *303 * @req:	asymmetric key request304 *305 * Return: zero on success; error code in case of error306 */307static inline int crypto_akcipher_decrypt(struct akcipher_request *req)308{309	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);310 311	return crypto_akcipher_alg(tfm)->decrypt(req);312}313 314/**315 * crypto_akcipher_sync_encrypt() - Invoke public key encrypt operation316 *317 * Function invokes the specific public key encrypt operation for a given318 * public key algorithm319 *320 * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()321 * @src:	source buffer322 * @slen:	source length323 * @dst:	destination obuffer324 * @dlen:	destination length325 *326 * Return: zero on success; error code in case of error327 */328int crypto_akcipher_sync_encrypt(struct crypto_akcipher *tfm,329				 const void *src, unsigned int slen,330				 void *dst, unsigned int dlen);331 332/**333 * crypto_akcipher_sync_decrypt() - Invoke public key decrypt operation334 *335 * Function invokes the specific public key decrypt operation for a given336 * public key algorithm337 *338 * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()339 * @src:	source buffer340 * @slen:	source length341 * @dst:	destination obuffer342 * @dlen:	destination length343 *344 * Return: Output length on success; error code in case of error345 */346int crypto_akcipher_sync_decrypt(struct crypto_akcipher *tfm,347				 const void *src, unsigned int slen,348				 void *dst, unsigned int dlen);349 350/**351 * crypto_akcipher_sign() - Invoke public key sign operation352 *353 * Function invokes the specific public key sign operation for a given354 * public key algorithm355 *356 * @req:	asymmetric key request357 *358 * Return: zero on success; error code in case of error359 */360static inline int crypto_akcipher_sign(struct akcipher_request *req)361{362	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);363 364	return crypto_akcipher_alg(tfm)->sign(req);365}366 367/**368 * crypto_akcipher_verify() - Invoke public key signature verification369 *370 * Function invokes the specific public key signature verification operation371 * for a given public key algorithm.372 *373 * @req:	asymmetric key request374 *375 * Note: req->dst should be NULL, req->src should point to SG of size376 * (req->src_size + req->dst_size), containing signature (of req->src_size377 * length) with appended digest (of req->dst_size length).378 *379 * Return: zero on verification success; error code in case of error.380 */381static inline int crypto_akcipher_verify(struct akcipher_request *req)382{383	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);384 385	return crypto_akcipher_alg(tfm)->verify(req);386}387 388/**389 * crypto_akcipher_set_pub_key() - Invoke set public key operation390 *391 * Function invokes the algorithm specific set key function, which knows392 * how to decode and interpret the encoded key and parameters393 *394 * @tfm:	tfm handle395 * @key:	BER encoded public key, algo OID, paramlen, BER encoded396 *		parameters397 * @keylen:	length of the key (not including other data)398 *399 * Return: zero on success; error code in case of error400 */401static inline int crypto_akcipher_set_pub_key(struct crypto_akcipher *tfm,402					      const void *key,403					      unsigned int keylen)404{405	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);406 407	return alg->set_pub_key(tfm, key, keylen);408}409 410/**411 * crypto_akcipher_set_priv_key() - Invoke set private key operation412 *413 * Function invokes the algorithm specific set key function, which knows414 * how to decode and interpret the encoded key and parameters415 *416 * @tfm:	tfm handle417 * @key:	BER encoded private key, algo OID, paramlen, BER encoded418 *		parameters419 * @keylen:	length of the key (not including other data)420 *421 * Return: zero on success; error code in case of error422 */423static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,424					       const void *key,425					       unsigned int keylen)426{427	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);428 429	return alg->set_priv_key(tfm, key, keylen);430}431#endif432