18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/**
38c2ecf20Sopenharmony_ci * Routines supporting VMX instructions on the Power 8
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2015 International Business Machines Inc.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/module.h>
118c2ecf20Sopenharmony_ci#include <linux/moduleparam.h>
128c2ecf20Sopenharmony_ci#include <linux/types.h>
138c2ecf20Sopenharmony_ci#include <linux/err.h>
148c2ecf20Sopenharmony_ci#include <linux/cpufeature.h>
158c2ecf20Sopenharmony_ci#include <linux/crypto.h>
168c2ecf20Sopenharmony_ci#include <asm/cputable.h>
178c2ecf20Sopenharmony_ci#include <crypto/internal/hash.h>
188c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciextern struct shash_alg p8_ghash_alg;
218c2ecf20Sopenharmony_ciextern struct crypto_alg p8_aes_alg;
228c2ecf20Sopenharmony_ciextern struct skcipher_alg p8_aes_cbc_alg;
238c2ecf20Sopenharmony_ciextern struct skcipher_alg p8_aes_ctr_alg;
248c2ecf20Sopenharmony_ciextern struct skcipher_alg p8_aes_xts_alg;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistatic int __init p8_init(void)
278c2ecf20Sopenharmony_ci{
288c2ecf20Sopenharmony_ci	int ret;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	ret = crypto_register_shash(&p8_ghash_alg);
318c2ecf20Sopenharmony_ci	if (ret)
328c2ecf20Sopenharmony_ci		goto err;
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	ret = crypto_register_alg(&p8_aes_alg);
358c2ecf20Sopenharmony_ci	if (ret)
368c2ecf20Sopenharmony_ci		goto err_unregister_ghash;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	ret = crypto_register_skcipher(&p8_aes_cbc_alg);
398c2ecf20Sopenharmony_ci	if (ret)
408c2ecf20Sopenharmony_ci		goto err_unregister_aes;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	ret = crypto_register_skcipher(&p8_aes_ctr_alg);
438c2ecf20Sopenharmony_ci	if (ret)
448c2ecf20Sopenharmony_ci		goto err_unregister_aes_cbc;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	ret = crypto_register_skcipher(&p8_aes_xts_alg);
478c2ecf20Sopenharmony_ci	if (ret)
488c2ecf20Sopenharmony_ci		goto err_unregister_aes_ctr;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	return 0;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cierr_unregister_aes_ctr:
538c2ecf20Sopenharmony_ci	crypto_unregister_skcipher(&p8_aes_ctr_alg);
548c2ecf20Sopenharmony_cierr_unregister_aes_cbc:
558c2ecf20Sopenharmony_ci	crypto_unregister_skcipher(&p8_aes_cbc_alg);
568c2ecf20Sopenharmony_cierr_unregister_aes:
578c2ecf20Sopenharmony_ci	crypto_unregister_alg(&p8_aes_alg);
588c2ecf20Sopenharmony_cierr_unregister_ghash:
598c2ecf20Sopenharmony_ci	crypto_unregister_shash(&p8_ghash_alg);
608c2ecf20Sopenharmony_cierr:
618c2ecf20Sopenharmony_ci	return ret;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic void __exit p8_exit(void)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	crypto_unregister_skcipher(&p8_aes_xts_alg);
678c2ecf20Sopenharmony_ci	crypto_unregister_skcipher(&p8_aes_ctr_alg);
688c2ecf20Sopenharmony_ci	crypto_unregister_skcipher(&p8_aes_cbc_alg);
698c2ecf20Sopenharmony_ci	crypto_unregister_alg(&p8_aes_alg);
708c2ecf20Sopenharmony_ci	crypto_unregister_shash(&p8_ghash_alg);
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cimodule_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, p8_init);
748c2ecf20Sopenharmony_cimodule_exit(p8_exit);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciMODULE_AUTHOR("Marcelo Cerri<mhcerri@br.ibm.com>");
778c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions "
788c2ecf20Sopenharmony_ci		   "support on Power 8");
798c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
808c2ecf20Sopenharmony_ciMODULE_VERSION("1.0.0");
81