net/ceph/crypto.c

Source file repositories/reference/linux-study-clean/net/ceph/crypto.c

File Facts

System
Linux kernel
Corpus path
net/ceph/crypto.c
Extension
.c
Size
12046 bytes
Lines
521
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (IS_ERR(key->krb5_tfms[i])) {
			ret = PTR_ERR(key->krb5_tfms[i]);
			key->krb5_tfms[i] = NULL;
			goto out_flag;
		}
	}

out_flag:
	memalloc_noio_restore(noio_flag);
	return ret;
}

int ceph_crypto_key_prepare(struct ceph_crypto_key *key,
			    const u32 *key_usages, int key_usage_cnt)
{
	switch (key->type) {
	case CEPH_CRYPTO_NONE:
		return 0; /* nothing to do */
	case CEPH_CRYPTO_AES:
		return set_aes_tfm(key);
	case CEPH_CRYPTO_AES256KRB5:
		hmac_sha256_preparekey(&key->hmac_key, key->key, key->len);
		return set_krb5_tfms(key, key_usages, key_usage_cnt);
	default:
		return -ENOTSUPP;
	}
}

/*
 * @dst should be zeroed before this function is called.
 */
int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
			  const struct ceph_crypto_key *src)
{
	dst->type = src->type;
	dst->created = src->created;
	dst->len = src->len;

	dst->key = kmemdup(src->key, src->len, GFP_NOIO);
	if (!dst->key)
		return -ENOMEM;

	return 0;
}

/*
 * @key should be zeroed before this function is called.
 */
int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
{
	ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
	key->type = ceph_decode_16(p);
	ceph_decode_copy(p, &key->created, sizeof(key->created));
	key->len = ceph_decode_16(p);
	ceph_decode_need(p, end, key->len, bad);
	if (key->len > CEPH_MAX_KEY_LEN) {
		pr_err("secret too big %d\n", key->len);
		return -EINVAL;
	}

	key->key = kmemdup(*p, key->len, GFP_NOIO);
	if (!key->key)
		return -ENOMEM;

	memzero_explicit(*p, key->len);
	*p += key->len;
	return 0;

bad:
	dout("failed to decode crypto key\n");
	return -EINVAL;
}

int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
{
	int inlen = strlen(inkey);
	int blen = inlen * 3 / 4;
	void *buf, *p;
	int ret;

	dout("crypto_key_unarmor %s\n", inkey);
	buf = kmalloc(blen, GFP_NOFS);
	if (!buf)
		return -ENOMEM;
	blen = ceph_unarmor(buf, inkey, inkey+inlen);
	if (blen < 0) {
		kfree(buf);
		return blen;
	}

Annotation

Implementation Notes