/*
 * Host AP crypto routines
 *
 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation. See README and COPYING for
 * more details.
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>

#include "rtllib.h"

struct rtllib_crypto_alg {
	struct list_head list;
	struct lib80211_crypto_ops *ops;
};


struct rtllib_crypto {
	struct list_head algs;
	spinlock_t lock;
};

static struct rtllib_crypto *hcrypt;

void rtllib_crypt_deinit_entries(struct lib80211_crypt_info *info,
					   int force)
{
	struct list_head *ptr, *n;
	struct lib80211_crypt_data *entry;

	for (ptr = info->crypt_deinit_list.next, n = ptr->next;
	     ptr != &info->crypt_deinit_list; ptr = n, n = ptr->next) {
		entry = list_entry(ptr, struct lib80211_crypt_data, list);

		if (atomic_read(&entry->refcnt) != 0 && !force)
			continue;

		list_del(ptr);

		if (entry->ops)
			entry->ops->deinit(entry->priv);
		kfree(entry);
	}
}
EXPORT_SYMBOL(rtllib_crypt_deinit_entries);

void rtllib_crypt_deinit_handler(unsigned long data)
{
	struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
	unsigned long flags;

	spin_lock_irqsave(info->lock, flags);
	rtllib_crypt_deinit_entries(info, 0);
	if (!list_empty(&info->crypt_deinit_list)) {
		printk(KERN_DEBUG
		       "%s: entries remaining in delayed crypt deletion list\n",
		       info->name);
		info->crypt_deinit_timer.expires = jiffies + HZ;
		add_timer(&info->crypt_deinit_timer);
	}
	spin_unlock_irqrestore(info->lock, flags);

}
EXPORT_SYMBOL(rtllib_crypt_deinit_handler);

void rtllib_crypt_delayed_deinit(struct lib80211_crypt_info *info,
				 struct lib80211_crypt_data **crypt)
{
	struct lib80211_crypt_data *tmp;
	unsigned long flags;

	if (*crypt == NULL)
		return;

	tmp = *crypt;
	*crypt = NULL;

	/* must not run ops->deinit() while there may be pending encrypt or
	 * decrypt operations. Use a list of delayed deinits to avoid needing
	 * locking.
	 */

	spin_lock_irqsave(info->lock, flags);
	list_add(&tmp->list, &info->crypt_deinit_list);
	if (!timer_pending(&info->crypt_deinit_timer)) {
		info->crypt_deinit_timer.expires = jiffies + HZ;
		add_timer(&info->crypt_deinit_timer);
	}
	spin_unlock_irqrestore(info->lock, flags);
}
EXPORT_SYMBOL(rtllib_crypt_delayed_deinit);

int rtllib_register_crypto_ops(struct lib80211_crypto_ops *ops)
{
	unsigned long flags;
	struct rtllib_crypto_alg *alg;

	if (hcrypt == NULL)
		return -1;

	alg = kzalloc(sizeof(*alg), GFP_KERNEL);
	if (alg == NULL)
		return -ENOMEM;

	alg->ops = ops;

	spin_lock_irqsave(&hcrypt->lock, flags);
	list_add(&alg->list, &hcrypt->algs);
	spin_unlock_irqrestore(&hcrypt->lock, flags);

	printk(KERN_DEBUG "rtllib_crypt: registered algorithm '%s'\n",
	       ops->name);

	return 0;
}
EXPORT_SYMBOL(rtllib_register_crypto_ops);

int rtllib_unregister_crypto_ops(struct lib80211_crypto_ops *ops)
{
	unsigned long flags;
	struct list_head *ptr;
	struct rtllib_crypto_alg *del_alg = NULL;

	if (hcrypt == NULL)
		return -1;

	spin_lock_irqsave(&hcrypt->lock, flags);
	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
		struct rtllib_crypto_alg *alg =
			(struct rtllib_crypto_alg *) ptr;
		if (alg->ops == ops) {
			list_del(&alg->list);
			del_alg = alg;
			break;
		}
	}
	spin_unlock_irqrestore(&hcrypt->lock, flags);

	if (del_alg) {
		printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm '%s'\n",
		       ops->name);
		kfree(del_alg);
	}

	return del_alg ? 0 : -1;
}
EXPORT_SYMBOL(rtllib_unregister_crypto_ops);


struct lib80211_crypto_ops *rtllib_get_crypto_ops(const char *name)
{
	unsigned long flags;
	struct list_head *ptr;
	struct rtllib_crypto_alg *found_alg = NULL;

	if (hcrypt == NULL)
		return NULL;

	spin_lock_irqsave(&hcrypt->lock, flags);
	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
		struct rtllib_crypto_alg *alg =
			(struct rtllib_crypto_alg *) ptr;
		if (strcmp(alg->ops->name, name) == 0) {
			found_alg = alg;
			break;
		}
	}
	spin_unlock_irqrestore(&hcrypt->lock, flags);

	if (found_alg)
		return found_alg->ops;
	else
		return NULL;
}
EXPORT_SYMBOL(rtllib_get_crypto_ops);


static void *rtllib_crypt_null_init(int keyidx) { return (void *) 1; }
static void rtllib_crypt_null_deinit(void *priv) {}

static struct lib80211_crypto_ops rtllib_crypt_null = {
	.name			= "NULL",
	.init			= rtllib_crypt_null_init,
	.deinit			= rtllib_crypt_null_deinit,
	.encrypt_mpdu		= NULL,
	.decrypt_mpdu		= NULL,
	.encrypt_msdu		= NULL,
	.decrypt_msdu		= NULL,
	.set_key		= NULL,
	.get_key		= NULL,
	.extra_mpdu_prefix_len	= 0,
	.extra_mpdu_postfix_len	= 0,
	.extra_msdu_prefix_len	= 0,
	.extra_msdu_postfix_len	= 0,
	.owner			= THIS_MODULE,
};


int __init rtllib_crypto_init(void)
{
	int ret = -ENOMEM;

	hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
	if (!hcrypt)
		goto out;

	INIT_LIST_HEAD(&hcrypt->algs);
	spin_lock_init(&hcrypt->lock);

	ret = lib80211_register_crypto_ops(&rtllib_crypt_null);
	if (ret < 0) {
		kfree(hcrypt);
		hcrypt = NULL;
	}
out:
	return ret;
}


void __exit rtllib_crypto_deinit(void)
{
	struct list_head *ptr, *n;

	if (hcrypt == NULL)
		return;

	for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
	     ptr = n, n = ptr->next) {
		struct rtllib_crypto_alg *alg =
			(struct rtllib_crypto_alg *) ptr;
		list_del(ptr);
		printk(KERN_DEBUG
		       "rtllib_crypt: unregistered algorithm '%s' (deinit)\n",
		       alg->ops->name);
		kfree(alg);
	}

	kfree(hcrypt);
}

module_init(rtllib_crypto_init);
module_exit(rtllib_crypto_deinit);

MODULE_LICENSE("GPL");
