// SPDX-License-Identifier: GPL-2.0
#include <linux/ceph/ceph_debug.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/ceph/decode.h>
#include <linux/ceph/auth.h>
#include <linux/ceph/ceph_features.h>
#include <linux/ceph/libceph.h>
#include <linux/ceph/messenger.h>
#include "crypto.h"
#include "auth_x.h"
#include "auth_x_protocol.h"
static const u32 ticket_key_usages[] = {
CEPHX_KEY_USAGE_TICKET_SESSION_KEY,
CEPHX_KEY_USAGE_TICKET_BLOB,
CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET
};
static const u32 authorizer_key_usages[] = {
CEPHX_KEY_USAGE_AUTHORIZE,
CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE,
CEPHX_KEY_USAGE_AUTHORIZE_REPLY
};
static const u32 client_key_usages[] = {
CEPHX_KEY_USAGE_TICKET_SESSION_KEY
};
static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
static int ceph_x_is_authenticated(struct ceph_auth_client *ac)
{
struct ceph_x_info *xi = ac->private;
int missing;
int need; /* missing + need renewal */
ceph_x_validate_tickets(ac, &need);
missing = ac->want_keys & ~xi->have_keys;
WARN_ON((need & missing) != missing);
dout("%s want 0x%x have 0x%x missing 0x%x -> %d\n", __func__,
ac->want_keys, xi->have_keys, missing, !missing);
return !missing;
}
static int ceph_x_should_authenticate(struct ceph_auth_client *ac)
{
struct ceph_x_info *xi = ac->private;
int need;
ceph_x_validate_tickets(ac, &need);
dout("%s want 0x%x have 0x%x need 0x%x -> %d\n", __func__,
ac->want_keys, xi->have_keys, need, !!need);
return !!need;
}
static int __ceph_x_encrypt_offset(const struct ceph_crypto_key *key)
{
return ceph_crypt_data_offset(key) +
sizeof(struct ceph_x_encrypt_header);
}
static int ceph_x_encrypt_offset(const struct ceph_crypto_key *key)
{
return sizeof(u32) + __ceph_x_encrypt_offset(key);
}
/*
* AES: ciphertext_len | hdr | data... | padding
* AES256KRB5: ciphertext_len | confounder | hdr | data... | hmac
*/
static int ceph_x_encrypt_buflen(const struct ceph_crypto_key *key,
int data_len)
{
int encrypt_len = sizeof(struct ceph_x_encrypt_header) + data_len;
return sizeof(u32) + ceph_crypt_buflen(key, encrypt_len);
}
static int ceph_x_encrypt(const struct ceph_crypto_key *key, int usage_slot,
void *buf, int buf_len, int plaintext_len)
{
struct ceph_x_encrypt_header *hdr;
int ciphertext_len;
int ret;
hdr = buf + sizeof(u32) + ceph_crypt_data_offset<