diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/crypto/algapi.h | 12 | ||||
-rw-r--r-- | include/linux/crypto.h | 270 |
2 files changed, 282 insertions, 0 deletions
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 418d270..4f5f331 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -125,6 +125,7 @@ struct ablkcipher_walk { extern const struct crypto_type crypto_ablkcipher_type; extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; +extern const struct crypto_type crypto_pkc_type; void crypto_mod_put(struct crypto_alg *alg); @@ -227,6 +228,11 @@ static inline void *crypto_ablkcipher_ctx(struct crypto_ablkcipher *tfm) return crypto_tfm_ctx(&tfm->base); } +static inline void *crypto_pkc_ctx(struct crypto_pkc *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + static inline void *crypto_ablkcipher_ctx_aligned(struct crypto_ablkcipher *tfm) { return crypto_tfm_ctx_aligned(&tfm->base); @@ -386,5 +392,11 @@ static inline int crypto_requires_sync(u32 type, u32 mask) return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC; } +/* RSA Request Completion handler */ +static inline void pkc_request_complete(struct pkc_request *req, + int err) +{ + req->base.complete(&req->base, err); +} #endif /* _CRYPTO_ALGAPI_H */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index b92eadf..69e9b5c 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -40,6 +40,8 @@ #define CRYPTO_ALG_TYPE_SHASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a #define CRYPTO_ALG_TYPE_RNG 0x0000000c +#define CRYPTO_ALG_TYPE_PKC_DSA 0x0000000d +#define CRYPTO_ALG_TYPE_PKC_RSA 0x0000000e #define CRYPTO_ALG_TYPE_PCOMPRESS 0x0000000f #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e @@ -175,6 +177,177 @@ struct aead_request { void *__ctx[] CRYPTO_MINALIGN_ATTR; }; +enum pkc_req_type { + RSA_PUB, + RSA_PRIV_FORM1, + RSA_PRIV_FORM2, + RSA_PRIV_FORM3, + DSA_SIGN, + DSA_VERIFY, + ECDSA_SIGN, + ECDSA_VERIFY, + MAX_TYPES +}; + +/* RSA Encrypt request Struct from cryptoAPI + @n - n, e represents the public key + @e - Public key exponent, n is modulus + @g - Output RSA-encrypted value + */ +struct rsa_pub_req_s { + uint8_t *n; + uint8_t *e; + uint8_t *g; + uint8_t *f; + uint32_t n_len; + uint32_t e_len; + uint32_t g_len; + uint32_t f_len; +}; + +/* RSA PrivKey Form1 + @n - n, d represents the private key form1 representation + @d - d is the private exponent, n is the modules + */ +struct rsa_priv_frm1_req_s { + uint8_t *n; + uint8_t *d; + uint8_t *f; + uint8_t *g; + uint32_t f_len; + uint32_t g_len; + uint32_t n_len; + uint32_t d_len; +}; + +/* RSA PrivKey Form2 + @n - p, q, d represents the private key form2 representation + @d - d is private exponent, p and q are the two primes + @f - output pointer + @g - input pointer + */ +struct rsa_priv_frm2_req_s { + uint8_t *p; + uint8_t *q; + uint8_t *d; + uint8_t *f; + uint8_t *g; + uint32_t f_len; + uint32_t g_len; + uint32_t p_len; + uint32_t q_len; + uint32_t d_len; + uint32_t n_len; +}; + +/* RSA PrivKey Form3 + @n - p, q, dp, dq, c represents the private key form3 representation + @dp - First CRT exponent factor + @dq - Second CRT exponent factor + @c - CRT Coefficient + @f - output pointer + @g - input pointer + */ +struct rsa_priv_frm3_req_s { + uint8_t *p; + uint8_t *q; + uint8_t *dp; + uint8_t *dq; + uint8_t *c; + uint8_t *f; + uint8_t *g; + uint32_t f_len; + uint32_t g_len; + uint32_t p_len; + uint32_t q_len; + uint32_t dp_len; + uint32_t dq_len; + uint32_t c_len; +}; + +/* DSA Sign request + @len_L - size of the field + @len_N - size of the group + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @f(or m) -Message representative (typically the hash of the message) + or the actual message,length N + @s - Own private key, length N + @c - First part of digital signature, length N + @d - Second part of digital signature. The buffer for d must be a + multiple of 16 bytes, as it is used to store an encrypted + intermediate result, which may include padding. Length N + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct dsa_sign_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *priv_key; + uint8_t *m; + uint8_t *c; + uint8_t *d; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t priv_key_len; + uint32_t m_len; + uint32_t d_len; + uint32_t ab_len; +}; + +/* DSA Verify request + @q -Prime number or irreducible polynomial that creates the field,length L + @r - Order of the field of private keys, length N + @g -Generator or generator point (ECC),length L or 2*L(ECC) + @f(or m) -Message representative (typically the hash of the message) + or the actual message,length N + @pub_key - Public key, length N + @c - First part of digital signature, length N + @d - Second part of digital signature. The buffer for d must be a + multiple of 16 bytes, as it is used to store an encrypted + intermediate result, which may include padding. Length N + @ab -ECC curve parameters(for ECC only). length 2*L + */ +struct dsa_verify_req_s { + uint8_t *q; + uint8_t *r; + uint8_t *g; + uint8_t *pub_key; + uint8_t *m; + uint8_t *c; + uint8_t *d; + uint8_t *ab; + uint32_t q_len; + uint32_t r_len; + uint32_t g_len; + uint32_t pub_key_len; + uint32_t m_len; + uint32_t d_len; + uint32_t ab_len; +}; + +/* + * PKC request structure to be provided by cryptoAPI to driver hook functions. + * The request may be generated by application via crytodev interface or within + * kernel via tcrypt etc. + */ +struct pkc_request { + struct crypto_async_request base; + + enum pkc_req_type type; + union { + struct rsa_pub_req_s rsa_pub_req; + struct rsa_priv_frm1_req_s rsa_priv_f1; + struct rsa_priv_frm2_req_s rsa_priv_f2; + struct rsa_priv_frm3_req_s rsa_priv_f3; + struct dsa_sign_req_s dsa_sign; + struct dsa_verify_req_s dsa_verify; + } req_u; +}; + struct blkcipher_desc { struct crypto_blkcipher *tfm; void *info; @@ -269,6 +442,13 @@ struct rng_alg { unsigned int seedsize; }; +struct pkc_alg { + /* Public Key Crypto Operation Handler */ + int (*pkc_op)(struct pkc_request *); + /* Minimum and Maximum Key size supported by driver */ + unsigned int min_keysize; + unsigned int max_keysize; +}; #define cra_ablkcipher cra_u.ablkcipher #define cra_aead cra_u.aead @@ -276,6 +456,7 @@ struct rng_alg { #define cra_cipher cra_u.cipher #define cra_compress cra_u.compress #define cra_rng cra_u.rng +#define cra_pkc cra_u.pkc struct crypto_alg { struct list_head cra_list; @@ -301,6 +482,7 @@ struct crypto_alg { struct cipher_alg cipher; struct compress_alg compress; struct rng_alg rng; + struct pkc_alg pkc; } cra_u; int (*cra_init)(struct crypto_tfm *tfm); @@ -402,6 +584,16 @@ struct rng_tfm { int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); }; +struct pkc_tfm { + /* Public Key Crypto Operation Handler */ + int (*pkc_op)(struct pkc_request *req); + + struct crypto_tfm *base; + + unsigned int min_keysize; + unsigned int max_keysize; +}; + #define crt_ablkcipher crt_u.ablkcipher #define crt_aead crt_u.aead #define crt_blkcipher crt_u.blkcipher @@ -409,6 +601,7 @@ struct rng_tfm { #define crt_hash crt_u.hash #define crt_compress crt_u.compress #define crt_rng crt_u.rng +#define crt_pkc crt_u.pkc struct crypto_tfm { @@ -422,6 +615,7 @@ struct crypto_tfm { struct hash_tfm hash; struct compress_tfm compress; struct rng_tfm rng; + struct pkc_tfm pkc; } crt_u; void (*exit)(struct crypto_tfm *tfm); @@ -447,6 +641,11 @@ struct crypto_cipher { struct crypto_tfm base; }; +/* PKC Transform structure */ +struct crypto_pkc { + struct crypto_tfm base; +}; + struct crypto_comp { struct crypto_tfm base; }; @@ -1015,6 +1214,77 @@ static inline void crypto_blkcipher_get_iv(struct crypto_blkcipher *tfm, memcpy(dst, crypto_blkcipher_crt(tfm)->iv, len); } +static inline struct crypto_tfm *crypto_pkc_tfm(struct crypto_pkc *tfm) +{ + return &tfm->base; +} + +static inline void pkc_request_set_tfm( + struct pkc_request *req, struct crypto_pkc *tfm) +{ + req->base.tfm = crypto_pkc_tfm(tfm); +} + +static inline struct pkc_request *pkc_request_alloc( + struct crypto_pkc *tfm, gfp_t gfp) +{ + struct pkc_request *req; + + req = kzalloc(sizeof(struct pkc_request), gfp); + + if (likely(req)) + pkc_request_set_tfm(req, tfm); + + return req; +} + +static inline void pkc_request_set_callback( + struct pkc_request *req, + u32 flags, crypto_completion_t complete, void *data) +{ + req->base.complete = complete; + req->base.data = data; + req->base.flags = flags; +} + +static inline struct crypto_pkc *__crypto_pkc_cast( + struct crypto_tfm *tfm) +{ + return (struct crypto_pkc *)tfm; +} + +static inline struct crypto_pkc *crypto_pkc_reqtfm( + struct pkc_request *req) +{ + return __crypto_pkc_cast(req->base.tfm); +} + +static inline struct crypto_pkc *crypto_alloc_pkc(const char *alg_name, + u32 type, u32 mask) +{ + mask |= CRYPTO_ALG_TYPE_MASK; + + return __crypto_pkc_cast(crypto_alloc_base(alg_name, type, mask)); +} + +static inline void crypto_free_pkc(struct crypto_pkc *tfm) +{ + crypto_free_tfm(crypto_pkc_tfm(tfm)); +} + +static inline struct pkc_tfm *crypto_pkc_crt( + struct crypto_pkc *tfm) +{ + return &crypto_pkc_tfm(tfm)->crt_pkc; +} + +static inline int crypto_pkc_op(struct pkc_request *req) +{ + struct pkc_tfm *tfm = + crypto_pkc_crt(crypto_pkc_reqtfm(req)); + return tfm->pkc_op(req); +} + static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm) { return (struct crypto_cipher *)tfm; |