@@ -165,7 +165,7 @@ static int ch_ipsec_setauthsize(struct xfrm_state *x,
static int ch_ipsec_setkey(struct xfrm_state *x,
struct ipsec_sa_entry *sa_entry)
{
- int keylen = (x->aead->alg_key_len + 7) / 8;
+ int keylen = xfrm_kblen2klen(x->aead->alg_key_len);
unsigned char *key = x->aead->alg_key;
int ck_size, key_ctx_size = 0;
unsigned char ghash_h[AEAD_H_SIZE];
@@ -323,7 +323,7 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
memset(attrs, 0, sizeof(*attrs));
/* key */
- crypto_data_len = (x->aead->alg_key_len + 7) / 8;
+ crypto_data_len = xfrm_kblen2klen(x->aead->alg_key_len);
key_len = crypto_data_len - 4; /* 4 bytes salt at end */
memcpy(aes_gcm->aes_key, x->aead->alg_key, key_len);
@@ -365,7 +365,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x,
}
if (x->aalg) {
- key_len = DIV_ROUND_UP(x->aalg->alg_key_len, BITS_PER_BYTE);
+ key_len = xfrm_kblen2klen(x->aalg->alg_key_len);
if (key_len > sizeof(cfg->auth_key)) {
NL_SET_ERR_MSG_MOD(extack, "Insufficient space for offloaded auth key");
return -EINVAL;
@@ -458,7 +458,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x,
int key_offset = 0;
int salt_len = 4;
- key_len = DIV_ROUND_UP(x->aead->alg_key_len, BITS_PER_BYTE);
+ key_len = xfrm_kblen2klen(x->aead->alg_key_len);
key_len -= salt_len;
if (key_len > sizeof(cfg->ciph_key)) {
@@ -485,7 +485,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x,
}
if (x->ealg) {
- key_len = DIV_ROUND_UP(x->ealg->alg_key_len, BITS_PER_BYTE);
+ key_len = xfrm_kblen2klen(x->ealg->alg_key_len);
if (key_len > sizeof(cfg->ciph_key)) {
NL_SET_ERR_MSG_MOD(extack, "ealg: Insufficient space for offloaded key");
@@ -1912,19 +1912,24 @@ static inline int xfrm_acquire_is_on(struct net *net)
}
#endif
+static inline unsigned int xfrm_kblen2klen(unsigned int klen_in_bits)
+{
+ return klen_in_bits / 8 + !!(klen_in_bits & 7);
+}
+
static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
{
- return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+ return sizeof(*alg) + xfrm_kblen2klen(alg->alg_key_len);
}
static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
{
- return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+ return sizeof(*alg) + xfrm_kblen2klen(alg->alg_key_len);
}
static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
{
- return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+ return sizeof(*alg) + xfrm_kblen2klen(alg->alg_key_len);
}
static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
@@ -496,7 +496,7 @@ static int ah_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
ahp->ahash = ahash;
if (crypto_ahash_setkey(ahash, x->aalg->alg_key,
- (x->aalg->alg_key_len + 7) / 8)) {
+ xfrm_kblen2klen(x->aalg->alg_key_len))) {
NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
}
@@ -1028,7 +1028,7 @@ static int esp_init_aead(struct xfrm_state *x, struct netlink_ext_ack *extack)
x->data = aead;
err = crypto_aead_setkey(aead, x->aead->alg_key,
- (x->aead->alg_key_len + 7) / 8);
+ xfrm_kblen2klen(x->aead->alg_key_len));
if (err)
goto error;
@@ -1088,8 +1088,9 @@ static int esp_init_authenc(struct xfrm_state *x,
x->data = aead;
- keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
- (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
+ keylen = x->aalg ? xfrm_kblen2klen(x->aalg->alg_key_len) : 0;
+ keylen += xfrm_kblen2klen(x->ealg->alg_key_len);
+ keylen += RTA_SPACE(sizeof(*param));
err = -ENOMEM;
key = kmalloc(keylen, GFP_KERNEL);
if (!key)
@@ -1105,8 +1106,8 @@ static int esp_init_authenc(struct xfrm_state *x,
if (x->aalg) {
struct xfrm_algo_desc *aalg_desc;
- memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8);
- p += (x->aalg->alg_key_len + 7) / 8;
+ memcpy(p, x->aalg->alg_key, xfrm_kblen2klen(x->aalg->alg_key_len));
+ p += xfrm_kblen2klen(x->aalg->alg_key_len);
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
@@ -1126,8 +1127,8 @@ static int esp_init_authenc(struct xfrm_state *x,
}
}
- param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
- memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
+ param->enckeylen = cpu_to_be32(xfrm_kblen2klen(x->ealg->alg_key_len));
+ memcpy(p, x->ealg->alg_key, xfrm_kblen2klen(x->ealg->alg_key_len));
err = crypto_aead_setkey(aead, key, keylen);
@@ -691,7 +691,7 @@ static int ah6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
ahp->ahash = ahash;
if (crypto_ahash_setkey(ahash, x->aalg->alg_key,
- (x->aalg->alg_key_len + 7) / 8)) {
+ xfrm_kblen2klen(x->aalg->alg_key_len))) {
NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
}
@@ -1065,7 +1065,7 @@ static int esp_init_aead(struct xfrm_state *x, struct netlink_ext_ack *extack)
x->data = aead;
err = crypto_aead_setkey(aead, x->aead->alg_key,
- (x->aead->alg_key_len + 7) / 8);
+ xfrm_kblen2klen(x->aead->alg_key_len));
if (err)
goto error;
@@ -1125,8 +1125,9 @@ static int esp_init_authenc(struct xfrm_state *x,
x->data = aead;
- keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) +
- (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param));
+ keylen = (x->aalg ? xfrm_kblen2klen(x->aalg->alg_key_len) : 0);
+ keylen += xfrm_kblen2klen(x->ealg->alg_key_len);
+ keylen += RTA_SPACE(sizeof(*param));
err = -ENOMEM;
key = kmalloc(keylen, GFP_KERNEL);
if (!key)
@@ -1142,8 +1143,8 @@ static int esp_init_authenc(struct xfrm_state *x,
if (x->aalg) {
struct xfrm_algo_desc *aalg_desc;
- memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8);
- p += (x->aalg->alg_key_len + 7) / 8;
+ memcpy(p, x->aalg->alg_key, xfrm_kblen2klen(x->aalg->alg_key_len));
+ p += xfrm_kblen2klen(x->aalg->alg_key_len);
aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
BUG_ON(!aalg_desc);
@@ -1163,8 +1164,8 @@ static int esp_init_authenc(struct xfrm_state *x,
}
}
- param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
- memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
+ param->enckeylen = cpu_to_be32(xfrm_kblen2klen(x->ealg->alg_key_len));
+ memcpy(p, x->ealg->alg_key, xfrm_kblen2klen(x->ealg->alg_key_len));
err = crypto_aead_setkey(aead, key, keylen);
@@ -803,13 +803,11 @@ static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x,
if (add_keys) {
if (x->aalg && x->aalg->alg_key_len) {
- auth_key_size =
- PFKEY_ALIGN8((x->aalg->alg_key_len + 7) / 8);
+ auth_key_size = PFKEY_ALIGN8(xfrm_kblen2klen(x->aalg->alg_key_len));
size += sizeof(struct sadb_key) + auth_key_size;
}
if (x->ealg && x->ealg->alg_key_len) {
- encrypt_key_size =
- PFKEY_ALIGN8((x->ealg->alg_key_len+7) / 8);
+ encrypt_key_size = PFKEY_ALIGN8(xfrm_kblen2klen(x->ealg->alg_key_len));
size += sizeof(struct sadb_key) + encrypt_key_size;
}
}
@@ -967,7 +965,8 @@ static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x,
key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
key->sadb_key_bits = x->aalg->alg_key_len;
key->sadb_key_reserved = 0;
- memcpy(key + 1, x->aalg->alg_key, (x->aalg->alg_key_len+7)/8);
+ memcpy(key + 1, x->aalg->alg_key,
+ xfrm_kblen2klen(x->aalg->alg_key_len));
}
/* encrypt key */
if (add_keys && encrypt_key_size) {
@@ -978,7 +977,7 @@ static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x,
key->sadb_key_bits = x->ealg->alg_key_len;
key->sadb_key_reserved = 0;
memcpy(key + 1, x->ealg->alg_key,
- (x->ealg->alg_key_len+7)/8);
+ xfrm_kblen2klen(x->ealg->alg_key_len));
}
/* sa */
@@ -532,6 +532,7 @@ static int attach_auth(struct xfrm_algo_auth **algpp, u8 *props,
struct xfrm_algo *ualg;
struct xfrm_algo_auth *p;
struct xfrm_algo_desc *algo;
+ unsigned int klen;
if (!rta)
return 0;
@@ -545,14 +546,15 @@ static int attach_auth(struct xfrm_algo_auth **algpp, u8 *props,
}
*props = algo->desc.sadb_alg_id;
- p = kmalloc(sizeof(*p) + (ualg->alg_key_len + 7) / 8, GFP_KERNEL);
+ klen = xfrm_kblen2klen(ualg->alg_key_len);
+ p = kmalloc(sizeof(*p) + klen, GFP_KERNEL);
if (!p)
return -ENOMEM;
strcpy(p->alg_name, algo->name);
p->alg_key_len = ualg->alg_key_len;
p->alg_trunc_len = algo->uinfo.auth.icv_truncbits;
- memcpy(p->alg_key, ualg->alg_key, (ualg->alg_key_len + 7) / 8);
+ memcpy(p->alg_key, ualg->alg_key, klen);
*algpp = p;
return 0;
@@ -1089,23 +1091,22 @@ static bool xfrm_redact(void)
static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
{
+ unsigned int klen = xfrm_kblen2klen(auth->alg_key_len);
struct xfrm_algo *algo;
struct xfrm_algo_auth *ap;
struct nlattr *nla;
bool redact_secret = xfrm_redact();
- nla = nla_reserve(skb, XFRMA_ALG_AUTH,
- sizeof(*algo) + (auth->alg_key_len + 7) / 8);
+ nla = nla_reserve(skb, XFRMA_ALG_AUTH, sizeof(*algo) + klen);
if (!nla)
return -EMSGSIZE;
algo = nla_data(nla);
strscpy_pad(algo->alg_name, auth->alg_name, sizeof(algo->alg_name));
- if (redact_secret && auth->alg_key_len)
- memset(algo->alg_key, 0, (auth->alg_key_len + 7) / 8);
+ if (redact_secret)
+ memset(algo->alg_key, 0, klen);
else
- memcpy(algo->alg_key, auth->alg_key,
- (auth->alg_key_len + 7) / 8);
+ memcpy(algo->alg_key, auth->alg_key, klen);
algo->alg_key_len = auth->alg_key_len;
nla = nla_reserve(skb, XFRMA_ALG_AUTH_TRUNC, xfrm_alg_auth_len(auth));
@@ -1115,16 +1116,16 @@ static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
strscpy_pad(ap->alg_name, auth->alg_name, sizeof(ap->alg_name));
ap->alg_key_len = auth->alg_key_len;
ap->alg_trunc_len = auth->alg_trunc_len;
- if (redact_secret && auth->alg_key_len)
- memset(ap->alg_key, 0, (auth->alg_key_len + 7) / 8);
+ if (redact_secret)
+ memset(ap->alg_key, 0, klen);
else
- memcpy(ap->alg_key, auth->alg_key,
- (auth->alg_key_len + 7) / 8);
+ memcpy(ap->alg_key, auth->alg_key, klen);
return 0;
}
static int copy_to_user_aead(struct xfrm_algo_aead *aead, struct sk_buff *skb)
{
+ unsigned int klen = xfrm_kblen2klen(aead->alg_key_len);
struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_AEAD, aead_len(aead));
struct xfrm_algo_aead *ap;
bool redact_secret = xfrm_redact();
@@ -1137,16 +1138,16 @@ static int copy_to_user_aead(struct xfrm_algo_aead *aead, struct sk_buff *skb)
ap->alg_key_len = aead->alg_key_len;
ap->alg_icv_len = aead->alg_icv_len;
- if (redact_secret && aead->alg_key_len)
- memset(ap->alg_key, 0, (aead->alg_key_len + 7) / 8);
+ if (redact_secret)
+ memset(ap->alg_key, 0, klen);
else
- memcpy(ap->alg_key, aead->alg_key,
- (aead->alg_key_len + 7) / 8);
+ memcpy(ap->alg_key, aead->alg_key, klen);
return 0;
}
static int copy_to_user_ealg(struct xfrm_algo *ealg, struct sk_buff *skb)
{
+ unsigned int klen = xfrm_kblen2klen(ealg->alg_key_len);
struct xfrm_algo *ap;
bool redact_secret = xfrm_redact();
struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_CRYPT,
@@ -1158,11 +1159,10 @@ static int copy_to_user_ealg(struct xfrm_algo *ealg, struct sk_buff *skb)
strscpy_pad(ap->alg_name, ealg->alg_name, sizeof(ap->alg_name));
ap->alg_key_len = ealg->alg_key_len;
- if (redact_secret && ealg->alg_key_len)
- memset(ap->alg_key, 0, (ealg->alg_key_len + 7) / 8);
+ if (redact_secret)
+ memset(ap->alg_key, 0, klen);
else
- memcpy(ap->alg_key, ealg->alg_key,
- (ealg->alg_key_len + 7) / 8);
+ memcpy(ap->alg_key, ealg->alg_key, klen);
return 0;
}
@@ -3509,7 +3509,7 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x)
l += nla_total_size(aead_len(x->aead));
if (x->aalg) {
l += nla_total_size(sizeof(struct xfrm_algo) +
- (x->aalg->alg_key_len + 7) / 8);
+ xfrm_kblen2klen(x->aalg->alg_key_len));
l += nla_total_size(xfrm_alg_auth_len(x->aalg));
}
if (x->ealg)