/*
 * 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");
