/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/obdclass/capa.c
 *
 * Lustre Capability Hash Management
 *
 * Author: Lai Siyao<lsy@clusterfs.com>
 */

#define DEBUG_SUBSYSTEM S_SEC

#include <linux/fs.h>
#include <asm/unistd.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/crypto.h>

#include "../include/obd_class.h"
#include "../include/lustre_debug.h"
#include "../include/lustre/lustre_idl.h"

#include <linux/list.h>
#include "../include/lustre_capa.h"

#define NR_CAPAHASH 32
#define CAPA_HASH_SIZE 3000	      /* for MDS & OSS */

struct kmem_cache *capa_cachep = NULL;

/* lock for capa hash/capa_list/fo_capa_keys */
DEFINE_SPINLOCK(capa_lock);

struct list_head capa_list[CAPA_SITE_MAX];

static struct capa_hmac_alg capa_hmac_algs[] = {
	DEF_CAPA_HMAC_ALG("sha1", SHA1, 20, 20),
};
/* capa count */
int capa_count[CAPA_SITE_MAX] = { 0, };

EXPORT_SYMBOL(capa_cachep);
EXPORT_SYMBOL(capa_list);
EXPORT_SYMBOL(capa_lock);
EXPORT_SYMBOL(capa_count);

static inline
unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm)
{
	return crypto_blkcipher_tfm(tfm)->__crt_alg->cra_blkcipher.min_keysize;
}

struct hlist_head *init_capa_hash(void)
{
	struct hlist_head *hash;
	int nr_hash, i;

	OBD_ALLOC(hash, PAGE_CACHE_SIZE);
	if (!hash)
		return NULL;

	nr_hash = PAGE_CACHE_SIZE / sizeof(struct hlist_head);
	LASSERT(nr_hash > NR_CAPAHASH);

	for (i = 0; i < NR_CAPAHASH; i++)
		INIT_HLIST_HEAD(hash + i);
	return hash;
}
EXPORT_SYMBOL(init_capa_hash);

static inline int capa_on_server(struct obd_capa *ocapa)
{
	return ocapa->c_site == CAPA_SITE_SERVER;
}

static inline void capa_delete(struct obd_capa *ocapa)
{
	LASSERT(capa_on_server(ocapa));
	hlist_del_init(&ocapa->u.tgt.c_hash);
	list_del_init(&ocapa->c_list);
	capa_count[ocapa->c_site]--;
	/* release the ref when alloc */
	capa_put(ocapa);
}

void cleanup_capa_hash(struct hlist_head *hash)
{
	int i;
	struct hlist_node *next;
	struct obd_capa *oc;

	spin_lock(&capa_lock);
	for (i = 0; i < NR_CAPAHASH; i++) {
		hlist_for_each_entry_safe(oc, next, hash + i,
					      u.tgt.c_hash)
			capa_delete(oc);
	}
	spin_unlock(&capa_lock);

	OBD_FREE(hash, PAGE_CACHE_SIZE);
}
EXPORT_SYMBOL(cleanup_capa_hash);

static inline int capa_hashfn(struct lu_fid *fid)
{
	return (fid_oid(fid) ^ fid_ver(fid)) *
	       (unsigned long)(fid_seq(fid) + 1) % NR_CAPAHASH;
}

/* capa renewal time check is earlier than that on client, which is to prevent
 * client renew right after obtaining it. */
static inline int capa_is_to_expire(struct obd_capa *oc)
{
	return time_before(cfs_time_sub(oc->c_expiry,
					cfs_time_seconds(oc->c_capa.lc_timeout)*2/3),
			   cfs_time_current());
}

static struct obd_capa *find_capa(struct lustre_capa *capa,
				  struct hlist_head *head, int alive)
{
	struct obd_capa *ocapa;
	int len = alive ? offsetof(struct lustre_capa, lc_keyid):sizeof(*capa);

	hlist_for_each_entry(ocapa, head, u.tgt.c_hash) {
		if (memcmp(&ocapa->c_capa, capa, len))
			continue;
		/* don't return one that will expire soon in this case */
		if (alive && capa_is_to_expire(ocapa))
			continue;

		LASSERT(capa_on_server(ocapa));

		DEBUG_CAPA(D_SEC, &ocapa->c_capa, "found");
		return ocapa;
	}

	return NULL;
}

#define LRU_CAPA_DELETE_COUNT 12
static inline void capa_delete_lru(struct list_head *head)
{
	struct obd_capa *ocapa;
	struct list_head *node = head->next;
	int count = 0;

	/* free LRU_CAPA_DELETE_COUNT unused capa from head */
	while (count++ < LRU_CAPA_DELETE_COUNT) {
		ocapa = list_entry(node, struct obd_capa, c_list);
		node = node->next;
		if (atomic_read(&ocapa->c_refc))
			continue;

		DEBUG_CAPA(D_SEC, &ocapa->c_capa, "free lru");
		capa_delete(ocapa);
	}
}

/* add or update */
struct obd_capa *capa_add(struct hlist_head *hash, struct lustre_capa *capa)
{
	struct hlist_head *head = hash + capa_hashfn(&capa->lc_fid);
	struct obd_capa *ocapa, *old = NULL;
	struct list_head *list = &capa_list[CAPA_SITE_SERVER];

	ocapa = alloc_capa(CAPA_SITE_SERVER);
	if (IS_ERR(ocapa))
		return NULL;

	spin_lock(&capa_lock);
	old = find_capa(capa, head, 0);
	if (!old) {
		ocapa->c_capa = *capa;
		set_capa_expiry(ocapa);
		hlist_add_head(&ocapa->u.tgt.c_hash, head);
		list_add_tail(&ocapa->c_list, list);
		capa_get(ocapa);
		capa_count[CAPA_SITE_SERVER]++;
		if (capa_count[CAPA_SITE_SERVER] > CAPA_HASH_SIZE)
			capa_delete_lru(list);
		spin_unlock(&capa_lock);
		return ocapa;
	}
	capa_get(old);
	spin_unlock(&capa_lock);
	capa_put(ocapa);
	return old;
}
EXPORT_SYMBOL(capa_add);

struct obd_capa *capa_lookup(struct hlist_head *hash, struct lustre_capa *capa,
			     int alive)
{
	struct obd_capa *ocapa;

	spin_lock(&capa_lock);
	ocapa = find_capa(capa, hash + capa_hashfn(&capa->lc_fid), alive);
	if (ocapa) {
		list_move_tail(&ocapa->c_list,
				   &capa_list[CAPA_SITE_SERVER]);
		capa_get(ocapa);
	}
	spin_unlock(&capa_lock);

	return ocapa;
}
EXPORT_SYMBOL(capa_lookup);

static inline int ll_crypto_hmac(struct crypto_hash *tfm,
				 u8 *key, unsigned int *keylen,
				 struct scatterlist *sg,
				 unsigned int size, u8 *result)
{
	struct hash_desc desc;
	int	      rv;
	desc.tfm   = tfm;
	desc.flags = 0;
	rv = crypto_hash_setkey(desc.tfm, key, *keylen);
	if (rv) {
		CERROR("failed to hash setkey: %d\n", rv);
		return rv;
	}
	return crypto_hash_digest(&desc, sg, size, result);
}

int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key)
{
	struct crypto_hash *tfm;
	struct capa_hmac_alg  *alg;
	int keylen;
	struct scatterlist sl;

	if (capa_alg(capa) != CAPA_HMAC_ALG_SHA1) {
		CERROR("unknown capability hmac algorithm!\n");
		return -EFAULT;
	}

	alg = &capa_hmac_algs[capa_alg(capa)];

	tfm = crypto_alloc_hash(alg->ha_name, 0, 0);
	if (IS_ERR(tfm)) {
		CERROR("crypto_alloc_tfm failed, check whether your kernel has crypto support!\n");
		return PTR_ERR(tfm);
	}
	keylen = alg->ha_keylen;

	sg_init_table(&sl, 1);
	sg_set_page(&sl, virt_to_page(capa),
		    offsetof(struct lustre_capa, lc_hmac),
		    (unsigned long)(capa) % PAGE_CACHE_SIZE);

	ll_crypto_hmac(tfm, key, &keylen, &sl, sl.length, hmac);
	crypto_free_hash(tfm);

	return 0;
}
EXPORT_SYMBOL(capa_hmac);

int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen)
{
	struct crypto_blkcipher *tfm;
	struct scatterlist sd;
	struct scatterlist ss;
	struct blkcipher_desc desc;
	unsigned int min;
	int rc;
	char alg[CRYPTO_MAX_ALG_NAME+1] = "aes";

	/* passing "aes" in a variable instead of a constant string keeps gcc
	 * 4.3.2 happy */
	tfm = crypto_alloc_blkcipher(alg, 0, 0);
	if (IS_ERR(tfm)) {
		CERROR("failed to load transform for aes\n");
		return PTR_ERR(tfm);
	}

	min = ll_crypto_tfm_alg_min_keysize(tfm);
	if (keylen < min) {
		CERROR("keylen at least %d bits for aes\n", min * 8);
		rc = -EINVAL;
		goto out;
	}

	rc = crypto_blkcipher_setkey(tfm, key, min);
	if (rc) {
		CERROR("failed to setting key for aes\n");
		goto out;
	}

	sg_init_table(&sd, 1);
	sg_set_page(&sd, virt_to_page(d), 16,
		    (unsigned long)(d) % PAGE_CACHE_SIZE);

	sg_init_table(&ss, 1);
	sg_set_page(&ss, virt_to_page(s), 16,
		    (unsigned long)(s) % PAGE_CACHE_SIZE);
	desc.tfm   = tfm;
	desc.info  = NULL;
	desc.flags = 0;
	rc = crypto_blkcipher_encrypt(&desc, &sd, &ss, 16);
	if (rc) {
		CERROR("failed to encrypt for aes\n");
		goto out;
	}

out:
	crypto_free_blkcipher(tfm);
	return rc;
}
EXPORT_SYMBOL(capa_encrypt_id);

int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen)
{
	struct crypto_blkcipher *tfm;
	struct scatterlist sd;
	struct scatterlist ss;
	struct blkcipher_desc desc;
	unsigned int min;
	int rc;
	char alg[CRYPTO_MAX_ALG_NAME+1] = "aes";

	/* passing "aes" in a variable instead of a constant string keeps gcc
	 * 4.3.2 happy */
	tfm = crypto_alloc_blkcipher(alg, 0, 0);
	if (IS_ERR(tfm)) {
		CERROR("failed to load transform for aes\n");
		return PTR_ERR(tfm);
	}

	min = ll_crypto_tfm_alg_min_keysize(tfm);
	if (keylen < min) {
		CERROR("keylen at least %d bits for aes\n", min * 8);
		rc = -EINVAL;
		goto out;
	}

	rc = crypto_blkcipher_setkey(tfm, key, min);
	if (rc) {
		CERROR("failed to setting key for aes\n");
		goto out;
	}

	sg_init_table(&sd, 1);
	sg_set_page(&sd, virt_to_page(d), 16,
		    (unsigned long)(d) % PAGE_CACHE_SIZE);

	sg_init_table(&ss, 1);
	sg_set_page(&ss, virt_to_page(s), 16,
		    (unsigned long)(s) % PAGE_CACHE_SIZE);

	desc.tfm   = tfm;
	desc.info  = NULL;
	desc.flags = 0;
	rc = crypto_blkcipher_decrypt(&desc, &sd, &ss, 16);
	if (rc) {
		CERROR("failed to decrypt for aes\n");
		goto out;
	}

out:
	crypto_free_blkcipher(tfm);
	return rc;
}
EXPORT_SYMBOL(capa_decrypt_id);

void capa_cpy(void *capa, struct obd_capa *ocapa)
{
	spin_lock(&ocapa->c_lock);
	*(struct lustre_capa *)capa = ocapa->c_capa;
	spin_unlock(&ocapa->c_lock);
}
EXPORT_SYMBOL(capa_cpy);

void _debug_capa(struct lustre_capa *c,
		 struct libcfs_debug_msg_data *msgdata,
		 const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	libcfs_debug_vmsg2(msgdata, fmt, args,
			   " capability@%p fid " DFID " opc %#llx uid %llu gid %llu flags %u alg %d keyid %u timeout %u expiry %u\n",
			   c, PFID(capa_fid(c)), capa_opc(c),
			   capa_uid(c), capa_gid(c), capa_flags(c),
			   capa_alg(c), capa_keyid(c), capa_timeout(c),
			   capa_expiry(c));
	va_end(args);
}
EXPORT_SYMBOL(_debug_capa);
