crypto: export interfaces abort aes-cmac

Signed-off-by: makejian <makejian@xiaomi.com>
This commit is contained in:
makejian 2024-07-08 21:01:44 +08:00 committed by Petro Karashchenko
parent 28974b8a21
commit 8de247543f
5 changed files with 139 additions and 82 deletions

View file

@ -224,6 +224,7 @@ static int cryptof_ioctl(FAR struct file *filep,
case CRYPTO_BLF_CBC:
case CRYPTO_CAST_CBC:
case CRYPTO_AES_CBC:
case CRYPTO_AES_CMAC:
case CRYPTO_AES_CTR:
case CRYPTO_AES_XTS:
case CRYPTO_AES_OFB:
@ -247,6 +248,7 @@ static int cryptof_ioctl(FAR struct file *filep,
case CRYPTO_SHA2_384_HMAC:
case CRYPTO_SHA2_512_HMAC:
case CRYPTO_AES_128_GMAC:
case CRYPTO_AES_128_CMAC:
case CRYPTO_MD5:
case CRYPTO_POLY1305:
case CRYPTO_RIPEMD160:
@ -384,14 +386,6 @@ int cryptodev_op(FAR struct csession *cse,
int error = OK;
uint32_t hid;
if (cse->txform)
{
if (cop->len == 0)
{
return -EINVAL;
}
}
/* number of requests, not logical and */
crp = crypto_getreq(cse->txform + cse->thash);

View file

@ -286,6 +286,7 @@ int swcr_authenc(FAR struct cryptop *crp)
FAR const struct auth_hash *axf = NULL;
FAR const struct enc_xform *exf = NULL;
caddr_t buf = (caddr_t)crp->crp_buf;
caddr_t aad = (caddr_t)crp->crp_aad;
FAR uint32_t *blkp;
int blksz = 0;
int ivlen = 0;
@ -310,6 +311,7 @@ int swcr_authenc(FAR struct cryptop *crp)
{
case CRYPTO_AES_GCM_16:
case CRYPTO_AES_GMAC:
case CRYPTO_AES_CMAC:
case CRYPTO_CHACHA20_POLY1305:
swe = sw;
crde = crd;
@ -319,6 +321,7 @@ int swcr_authenc(FAR struct cryptop *crp)
case CRYPTO_AES_128_GMAC:
case CRYPTO_AES_192_GMAC:
case CRYPTO_AES_256_GMAC:
case CRYPTO_AES_128_CMAC:
case CRYPTO_CHACHA20_POLY1305_MAC:
swa = sw;
crda = crd;
@ -388,38 +391,41 @@ int swcr_authenc(FAR struct cryptop *crp)
/* Supply MAC with AAD */
aadlen = crda->crd_len;
/* Section 5 of RFC 4106 specifies that AAD construction consists of
* {SPI, ESN, SN} whereas the real packet contains only {SPI, SN}.
* Unfortunately it doesn't follow a good example set in the Section
* 3.3.2.1 of RFC 4303 where upper part of the ESN, located in the
* external (to the packet) memory buffer, is processed by the hash
* function in the end thus allowing to retain simple programming
* interfaces and avoid kludges like the one below.
*/
if (crda->crd_flags & CRD_F_ESN)
if (aad)
{
aadlen += 4;
aadlen = crda->crd_len;
/* Section 5 of RFC 4106 specifies that AAD construction consists of
* {SPI, ESN, SN} whereas the real packet contains only {SPI, SN}.
* Unfortunately it doesn't follow a good example set in the Section
* 3.3.2.1 of RFC 4303 where upper part of the ESN, located in the
* external (to the packet) memory buffer, is processed by the hash
* function in the end thus allowing to retain simple programming
* interfaces and avoid kludges like the one below.
*/
/* SPI */
if (crda->crd_flags & CRD_F_ESN)
{
aadlen += 4;
bcopy(buf + crda->crd_skip, blk, 4);
iskip = 4; /* loop below will start with an offset of 4 */
/* SPI */
/* ESN */
bcopy(buf + crda->crd_skip, blk, 4);
iskip = 4; /* loop below will start with an offset of 4 */
bcopy(crda->crd_esn, blk + 4, 4);
oskip = iskip + 4; /* offset output buffer blk by 8 */
}
/* ESN */
for (i = iskip; i < crda->crd_len; i += axf->hashsize)
{
len = MIN(crda->crd_len - i, axf->hashsize - oskip);
bcopy(buf + crda->crd_skip + i, blk + oskip, len);
bzero(blk + len + oskip, axf->hashsize - len - oskip);
axf->update(&ctx, blk, axf->hashsize);
oskip = 0; /* reset initial output offset */
bcopy(crda->crd_esn, blk + 4, 4);
oskip = iskip + 4; /* offset output buffer blk by 8 */
}
for (i = iskip; i < crda->crd_len; i += axf->hashsize)
{
len = MIN(crda->crd_len - i, axf->hashsize - oskip);
bcopy(buf + crda->crd_skip + i, blk + oskip, len);
bzero(blk + len + oskip, axf->hashsize - len - oskip);
axf->update(&ctx, blk, axf->hashsize);
oskip = 0; /* reset initial output offset */
}
}
if (exf->reinit)
@ -429,68 +435,77 @@ int swcr_authenc(FAR struct cryptop *crp)
/* Do encryption/decryption with MAC */
for (i = 0; i < crde->crd_len; i += blksz)
if (buf)
{
len = MIN(crde->crd_len - i, blksz);
if (len < blksz)
for (i = 0; i < crde->crd_len; i += blksz)
{
bzero(blk, blksz);
}
len = MIN(crde->crd_len - i, blksz);
if (len < blksz)
{
bzero(blk, blksz);
}
bcopy(buf + i, blk, len);
if (crde->crd_flags & CRD_F_ENCRYPT)
{
exf->encrypt((caddr_t)swe->sw_kschedule, blk);
axf->update(&ctx, blk, len);
}
else
{
axf->update(&ctx, blk, len);
exf->decrypt((caddr_t)swe->sw_kschedule, blk);
}
bcopy(buf + i, blk, len);
if (crde->crd_flags & CRD_F_ENCRYPT)
{
exf->encrypt((caddr_t)swe->sw_kschedule, blk);
axf->update(&ctx, blk, len);
}
else
{
axf->update(&ctx, blk, len);
exf->decrypt((caddr_t)swe->sw_kschedule, blk);
}
bcopy(blk, crp->crp_dst + i, len);
if (crp->crp_dst)
{
bcopy(blk, crp->crp_dst + i, len);
}
}
}
/* Do any required special finalization */
switch (crda->crd_alg)
if (crp->crp_mac)
{
case CRYPTO_AES_128_GMAC:
case CRYPTO_AES_192_GMAC:
case CRYPTO_AES_256_GMAC:
switch (crda->crd_alg)
{
case CRYPTO_AES_128_GMAC:
case CRYPTO_AES_192_GMAC:
case CRYPTO_AES_256_GMAC:
/* length block */
/* length block */
bzero(blk, axf->hashsize);
blkp = (uint32_t *)blk + 1;
*blkp = htobe32(aadlen * 8);
blkp = (uint32_t *)blk + 3;
*blkp = htobe32(crde->crd_len * 8);
axf->update(&ctx, blk, axf->hashsize);
break;
bzero(blk, axf->hashsize);
blkp = (uint32_t *)blk + 1;
*blkp = htobe32(aadlen * 8);
blkp = (uint32_t *)blk + 3;
*blkp = htobe32(crde->crd_len * 8);
axf->update(&ctx, blk, axf->hashsize);
break;
case CRYPTO_CHACHA20_POLY1305_MAC:
case CRYPTO_CHACHA20_POLY1305_MAC:
/* length block */
/* length block */
bzero(blk, axf->hashsize);
blkp = (uint32_t *)blk;
*blkp = htole32(aadlen);
blkp = (uint32_t *)blk + 2;
*blkp = htole32(crde->crd_len);
axf->update(&ctx, blk, axf->hashsize);
break;
bzero(blk, axf->hashsize);
blkp = (uint32_t *)blk;
*blkp = htole32(aadlen);
blkp = (uint32_t *)blk + 2;
*blkp = htole32(crde->crd_len);
axf->update(&ctx, blk, axf->hashsize);
break;
}
/* Finalize MAC */
axf->final(aalg, &ctx);
/* Inject the authentication data */
bcopy(aalg, crp->crp_mac, axf->authsize);
}
/* Finalize MAC */
axf->final(aalg, &ctx);
/* Inject the authentication data */
bcopy(aalg, crp->crp_mac, axf->authsize);
return 0;
}
@ -660,6 +675,10 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct cryptoini *cri)
txf = &enc_xform_aes_gmac;
(*swd)->sw_exf = txf;
break;
case CRYPTO_AES_CMAC:
txf = &enc_xform_aes_cmac;
(*swd)->sw_exf = txf;
break;
case CRYPTO_AES_OFB:
txf = &enc_xform_aes_ofb;
goto enccommon;
@ -831,6 +850,10 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct cryptoini *cri)
axf = &auth_hash_gmac_aes_256;
goto auth4common;
case CRYPTO_AES_128_CMAC:
axf = &auth_hash_cmac_aes_128;
goto auth4common;
case CRYPTO_POLY1305:
axf = &auth_hash_poly1305;
goto auth4common;
@ -911,6 +934,7 @@ int swcr_freesession(uint64_t tid)
case CRYPTO_AES_XTS:
case CRYPTO_AES_GCM_16:
case CRYPTO_AES_GMAC:
case CRYPTO_AES_CMAC:
case CRYPTO_AES_OFB:
case CRYPTO_AES_CFB_8:
case CRYPTO_AES_CFB_128:
@ -951,6 +975,7 @@ int swcr_freesession(uint64_t tid)
case CRYPTO_AES_128_GMAC:
case CRYPTO_AES_192_GMAC:
case CRYPTO_AES_256_GMAC:
case CRYPTO_AES_128_CMAC:
case CRYPTO_CHACHA20_POLY1305_MAC:
case CRYPTO_MD5:
case CRYPTO_POLY1305:
@ -1109,6 +1134,7 @@ int swcr_process(struct cryptop *crp)
case CRYPTO_AES_128_GMAC:
case CRYPTO_AES_192_GMAC:
case CRYPTO_AES_256_GMAC:
case CRYPTO_AES_128_CMAC:
case CRYPTO_CHACHA20_POLY1305:
case CRYPTO_CHACHA20_POLY1305_MAC:
crp->crp_etype = swcr_authenc(crp);
@ -1237,6 +1263,8 @@ void swcr_init(void)
algs[CRYPTO_SHA2_384] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_SHA2_512] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_CRC32] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_AES_CMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_AES_128_CMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_ESN] = CRYPTO_ALG_FLAG_SUPPORTED;
crypto_register(swcr_id, algs, swcr_newsession,

View file

@ -70,6 +70,7 @@
#include <crypto/cryptodev.h>
#include <crypto/xform.h>
#include <crypto/gmac.h>
#include <crypto/cmac.h>
#include <crypto/chachapoly.h>
#include <crypto/poly1305.h>
#include <nuttx/crc32.h>
@ -240,6 +241,16 @@ const struct enc_xform enc_xform_aes_gmac =
NULL
};
const struct enc_xform enc_xform_aes_cmac =
{
CRYPTO_AES_CMAC, "AES-CMAC",
1, 0, 16, 32, 0,
null_encrypt,
null_decrypt,
null_setkey,
NULL
};
const struct enc_xform enc_xform_aes_xts =
{
CRYPTO_AES_XTS, "AES-XTS",
@ -395,6 +406,16 @@ const struct auth_hash auth_hash_chacha20_poly1305 =
chacha20_poly1305_final
};
const struct auth_hash auth_hash_cmac_aes_128 =
{
CRYPTO_AES_128_CMAC, "CMAC-AES-128",
16, AES_CMAC_KEY_LENGTH, AES_CMAC_DIGEST_LENGTH, sizeof(AES_CMAC_CTX),
AESCTR_BLOCKSIZE, (void (*)(FAR void *)) aes_cmac_init,
(void (*)(FAR void *, FAR const uint8_t *, uint16_t)) aes_cmac_setkey,
NULL, (int (*)(FAR void *, FAR const uint8_t *, size_t)) aes_cmac_update,
(void (*) (FAR uint8_t *, FAR void *)) aes_cmac_final
};
const struct auth_hash auth_hash_md5 =
{
CRYPTO_MD5, "MD5",

View file

@ -125,8 +125,10 @@
#define CRYPTO_SHA2_384 32
#define CRYPTO_SHA2_512 33
#define CRYPTO_CRC32 34
#define CRYPTO_ESN 35 /* Support for Extended Sequence Numbers */
#define CRYPTO_ALGORITHM_MAX 35 /* Keep updated */
#define CRYPTO_AES_CMAC 35
#define CRYPTO_AES_128_CMAC 36
#define CRYPTO_ESN 37 /* Support for Extended Sequence Numbers */
#define CRYPTO_ALGORITHM_MAX 37 /* Keep updated */
/* Algorithm flags */
@ -170,6 +172,7 @@ struct cryptodesc
#define CRD_F_COMP 0x10 /* Set when doing compression */
#define CRD_F_ESN 0x20 /* Set when ESN field is provided */
#define CRD_F_UPDATE 0x40 /* Set just update source */
#define CRD_F_UPDATE_AAD 0x80 /* Set just update aad */
struct cryptoini CRD_INI; /* Initialization/context data */
#define crd_esn CRD_INI.cri_esn
@ -200,6 +203,7 @@ struct cryptop
* value on future requests.
*/
int crp_flags;
int crp_aadlen;
#define CRYPTO_F_IMBUF 0x0001 /* Input/output are mbuf chains, otherwise contig */
#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
@ -216,6 +220,7 @@ struct cryptop
caddr_t crp_mac;
caddr_t crp_dst;
caddr_t crp_iv;
caddr_t crp_aad;
};
#define CRYPTO_BUF_IOV 0x1
@ -330,12 +335,19 @@ struct crypt_op
* be used, and the subsequent iv will be saved
* in the driver.
*/
#define COP_FLAG_UPDATE_AAD (1 << 1)
/* Indicates that this operation processes aad
* (Additional Authenticated Data), which is only used
* in the authentication algorithm.
*/
uint16_t flags;
unsigned len;
unsigned aadlen;
caddr_t src, dst; /* become iov[] inside kernel */
caddr_t mac; /* must be big enough for chosen MAC */
caddr_t iv;
caddr_t aad;
};
/* hamc buffer, software & hardware need it */

View file

@ -103,6 +103,7 @@ extern const struct enc_xform enc_xform_aes;
extern const struct enc_xform enc_xform_aes_ctr;
extern const struct enc_xform enc_xform_aes_gcm;
extern const struct enc_xform enc_xform_aes_gmac;
extern const struct enc_xform enc_xform_aes_cmac;
extern const struct enc_xform enc_xform_aes_xts;
extern const struct enc_xform enc_xform_aes_ofb;
extern const struct enc_xform enc_xform_aes_cfb_8;
@ -129,5 +130,6 @@ extern const struct auth_hash auth_hash_sha2_256;
extern const struct auth_hash auth_hash_sha2_384;
extern const struct auth_hash auth_hash_sha2_512;
extern const struct auth_hash auth_hash_crc32;
extern const struct auth_hash auth_hash_cmac_aes_128;
#endif /* __INCLUDE_CRYPTO_XFORM_H */