diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index aaa89a11ba..d810079008 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -588,6 +588,10 @@ int cryptodev_key(FAR struct crypt_kop *kop) if (in == 3 && out == 1) break; return -EINVAL; + case CRK_RSA_PCKS15_VERIFY: + if (in == 5 && out == 0) + break; + return -EINVAL; default: return -EINVAL; } diff --git a/crypto/cryptosoft.c b/crypto/cryptosoft.c index 1281e70281..fc007eb5cd 100644 --- a/crypto/cryptosoft.c +++ b/crypto/cryptosoft.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -1097,11 +1098,72 @@ done: return 0; } +int swcr_rsa_verify(struct cryptkop *krp) +{ + uint8_t *exp = (uint8_t *)krp->krp_param[0].crp_p; + uint8_t *modulus = (uint8_t *)krp->krp_param[1].crp_p; + uint8_t *sig = (uint8_t *)krp->krp_param[2].crp_p; + uint8_t *hash = (uint8_t *)krp->krp_param[3].crp_p; + uint8_t *padding = (uint8_t *)krp->krp_param[4].crp_p; + int exp_len = krp->krp_param[0].crp_nbits / 8; + int modulus_len = krp->krp_param[1].crp_nbits / 8; + int sig_len = krp->krp_param[2].crp_nbits / 8; + int hash_len = krp->krp_param[3].crp_nbits / 8; + int padding_len = krp->krp_param[4].crp_nbits / 8; + struct bn a; + struct bn e; + struct bn n; + struct bn r; + + bignum_init(&a); + bignum_init(&e); + bignum_init(&n); + bignum_init(&r); + memcpy(e.array, exp, exp_len); + memcpy(n.array, modulus, modulus_len); + memcpy(a.array, sig, sig_len); + pow_mod_faster(&a, &e, &n, &r); + return !!memcmp(r.array, hash, hash_len) + + !!memcmp(r.array + hash_len, padding, padding_len); +} + +int swcr_kprocess(struct cryptkop *krp) +{ + /* Sanity check */ + + if (krp == NULL) + { + return -EINVAL; + } + + /* Go through crypto descriptors, processing as we go */ + + switch (krp->krp_op) + { + case CRK_RSA_PCKS15_VERIFY: + if ((krp->krp_status = swcr_rsa_verify(krp)) != 0) + { + goto done; + } + break; + default: + + /* Unknown/unsupported algorithm */ + + krp->krp_status = -EINVAL; + goto done; + } + +done: + return 0; +} + /* Initialize the driver, called from the kernel main(). */ void swcr_init(void) { int algs[CRYPTO_ALGORITHM_MAX + 1]; + int kalgs[CRK_ALGORITHM_MAX + 1]; int flags = CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_ENCRYPT_MAC | CRYPTOCAP_F_MAC_ENCRYPT; @@ -1146,4 +1208,7 @@ void swcr_init(void) crypto_register(swcr_id, algs, swcr_newsession, swcr_freesession, swcr_process); + + kalgs[CRK_RSA_PCKS15_VERIFY] = CRYPTO_ALG_FLAG_SUPPORTED; + crypto_kregister(swcr_id, kalgs, swcr_kprocess); } diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h index 9357669647..86c8e7e4dd 100644 --- a/include/crypto/cryptodev.h +++ b/include/crypto/cryptodev.h @@ -240,18 +240,20 @@ struct crypt_kop struct crparam crk_param[CRK_MAXPARAM]; }; -#define CRK_MOD_EXP 0 -#define CRK_MOD_EXP_CRT 1 -#define CRK_DSA_SIGN 2 -#define CRK_DSA_VERIFY 3 -#define CRK_DH_COMPUTE_KEY 4 -#define CRK_ALGORITHM_MAX 4 /* Keep updated */ +#define CRK_MOD_EXP 0 +#define CRK_MOD_EXP_CRT 1 +#define CRK_DSA_SIGN 2 +#define CRK_DSA_VERIFY 3 +#define CRK_DH_COMPUTE_KEY 4 +#define CRK_RSA_PCKS15_VERIFY 5 +#define CRK_ALGORITHM_MAX 5 /* Keep updated */ -#define CRF_MOD_EXP (1 << CRK_MOD_EXP) -#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT) -#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN) -#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY) -#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY) +#define CRF_MOD_EXP (1 << CRK_MOD_EXP) +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT) +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN) +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY) +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY) +#define CRF_RSA_PCKS15_VERIFY (1 << CRK_RSA_PCKS15_VERIFY) struct cryptkop { diff --git a/include/crypto/cryptosoft.h b/include/crypto/cryptosoft.h index 36aca9a838..e28f935412 100644 --- a/include/crypto/cryptosoft.h +++ b/include/crypto/cryptosoft.h @@ -83,7 +83,9 @@ int swcr_authcompute(FAR struct cryptop *, FAR struct cryptodesc *, int swcr_authenc(FAR struct cryptop *); int swcr_compdec(FAR struct cryptodesc *, FAR struct swcr_data *, caddr_t, int); +int swcr_rsa_verify(FAR struct cryptkop *); int swcr_process(FAR struct cryptop *); +int swcr_kprocess(FAR struct cryptkop *); int swcr_newsession(FAR uint32_t *, FAR struct cryptoini *); int swcr_freesession(uint64_t); void swcr_init(void);