162306a36Sopenharmony_ci#ifndef _CRYPTO_GCM_H
262306a36Sopenharmony_ci#define _CRYPTO_GCM_H
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include <linux/errno.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <crypto/aes.h>
762306a36Sopenharmony_ci#include <crypto/gf128mul.h>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#define GCM_AES_IV_SIZE 12
1062306a36Sopenharmony_ci#define GCM_RFC4106_IV_SIZE 8
1162306a36Sopenharmony_ci#define GCM_RFC4543_IV_SIZE 8
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/*
1462306a36Sopenharmony_ci * validate authentication tag for GCM
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_cistatic inline int crypto_gcm_check_authsize(unsigned int authsize)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	switch (authsize) {
1962306a36Sopenharmony_ci	case 4:
2062306a36Sopenharmony_ci	case 8:
2162306a36Sopenharmony_ci	case 12:
2262306a36Sopenharmony_ci	case 13:
2362306a36Sopenharmony_ci	case 14:
2462306a36Sopenharmony_ci	case 15:
2562306a36Sopenharmony_ci	case 16:
2662306a36Sopenharmony_ci		break;
2762306a36Sopenharmony_ci	default:
2862306a36Sopenharmony_ci		return -EINVAL;
2962306a36Sopenharmony_ci	}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	return 0;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/*
3562306a36Sopenharmony_ci * validate authentication tag for RFC4106
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_cistatic inline int crypto_rfc4106_check_authsize(unsigned int authsize)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	switch (authsize) {
4062306a36Sopenharmony_ci	case 8:
4162306a36Sopenharmony_ci	case 12:
4262306a36Sopenharmony_ci	case 16:
4362306a36Sopenharmony_ci		break;
4462306a36Sopenharmony_ci	default:
4562306a36Sopenharmony_ci		return -EINVAL;
4662306a36Sopenharmony_ci	}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	return 0;
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/*
5262306a36Sopenharmony_ci * validate assoclen for RFC4106/RFC4543
5362306a36Sopenharmony_ci */
5462306a36Sopenharmony_cistatic inline int crypto_ipsec_check_assoclen(unsigned int assoclen)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	switch (assoclen) {
5762306a36Sopenharmony_ci	case 16:
5862306a36Sopenharmony_ci	case 20:
5962306a36Sopenharmony_ci		break;
6062306a36Sopenharmony_ci	default:
6162306a36Sopenharmony_ci		return -EINVAL;
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	return 0;
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistruct aesgcm_ctx {
6862306a36Sopenharmony_ci	be128			ghash_key;
6962306a36Sopenharmony_ci	struct crypto_aes_ctx	aes_ctx;
7062306a36Sopenharmony_ci	unsigned int		authsize;
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciint aesgcm_expandkey(struct aesgcm_ctx *ctx, const u8 *key,
7462306a36Sopenharmony_ci		     unsigned int keysize, unsigned int authsize);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_civoid aesgcm_encrypt(const struct aesgcm_ctx *ctx, u8 *dst, const u8 *src,
7762306a36Sopenharmony_ci		    int crypt_len, const u8 *assoc, int assoc_len,
7862306a36Sopenharmony_ci		    const u8 iv[GCM_AES_IV_SIZE], u8 *authtag);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cibool __must_check aesgcm_decrypt(const struct aesgcm_ctx *ctx, u8 *dst,
8162306a36Sopenharmony_ci				 const u8 *src, int crypt_len, const u8 *assoc,
8262306a36Sopenharmony_ci				 int assoc_len, const u8 iv[GCM_AES_IV_SIZE],
8362306a36Sopenharmony_ci				 const u8 *authtag);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#endif
86