[PATCH RFC 070/104] crypto: fips140: convert crypto/shash.c to using crypto API wrappers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use CRYPTO_API() etc. from include/crypto/api.h in preparation for
compilation as part of support for FIPS 140 standalone modules.

Generated using:

  ./fipsify.py --config CONFIG_CRYPTO_HASH2 --source crypto/shash.c --header include/crypto/hash.h include/crypto/internal/hash.h

Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxxx>
---
 crypto/fips140-api.c           | 33 ++++++++++++++
 crypto/shash.c                 | 80 +++++++++++++++++-----------------
 include/crypto/hash.h          | 45 ++++++++++++-------
 include/crypto/internal/hash.h | 43 ++++++++++++------
 4 files changed, 133 insertions(+), 68 deletions(-)

diff --git a/crypto/fips140-api.c b/crypto/fips140-api.c
index 2567c6d6622f..eec551e120e2 100644
--- a/crypto/fips140-api.c
+++ b/crypto/fips140-api.c
@@ -511,3 +511,36 @@ DEFINE_CRYPTO_API_STUB(crypto_sha3_init);
 
 #endif
 
+/*
+ * crypto/shash.c
+ */
+#if !IS_BUILTIN(CONFIG_CRYPTO_HASH2)
+
+#include <crypto/hash.h>
+
+DEFINE_CRYPTO_API_STUB(crypto_alloc_shash);
+DEFINE_CRYPTO_API_STUB(crypto_clone_shash);
+DEFINE_CRYPTO_API_STUB(crypto_has_shash);
+DEFINE_CRYPTO_API_STUB(crypto_shash_setkey);
+DEFINE_CRYPTO_API_STUB(crypto_shash_digest);
+DEFINE_CRYPTO_API_STUB(crypto_shash_tfm_digest);
+DEFINE_CRYPTO_API_STUB(crypto_shash_export);
+DEFINE_CRYPTO_API_STUB(crypto_shash_import);
+DEFINE_CRYPTO_API_STUB(crypto_shash_init);
+DEFINE_CRYPTO_API_STUB(crypto_shash_finup);
+
+#include <crypto/internal/hash.h>
+
+DEFINE_CRYPTO_API_STUB(crypto_shash_alg_has_setkey);
+DEFINE_CRYPTO_API_STUB(crypto_register_shash);
+DEFINE_CRYPTO_API_STUB(crypto_unregister_shash);
+DEFINE_CRYPTO_API_STUB(crypto_register_shashes);
+DEFINE_CRYPTO_API_STUB(crypto_unregister_shashes);
+DEFINE_CRYPTO_API_STUB(shash_register_instance);
+DEFINE_CRYPTO_API_STUB(shash_free_singlespawn_instance);
+DEFINE_CRYPTO_API_STUB(crypto_grab_shash);
+DEFINE_CRYPTO_API_STUB(crypto_shash_export_core);
+DEFINE_CRYPTO_API_STUB(crypto_shash_import_core);
+
+#endif
+
diff --git a/crypto/shash.c b/crypto/shash.c
index d45d7ec83a8c..9f154cebbb95 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -47,11 +47,11 @@ static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
  * when CFI is enabled, modules won't get the same address for shash_no_setkey
  * (if it were exported, which inlining would require) as the core kernel will.
  */
-bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
+bool CRYPTO_API(crypto_shash_alg_has_setkey)(struct shash_alg *alg)
 {
 	return alg->setkey != shash_no_setkey;
 }
-EXPORT_SYMBOL_GPL(crypto_shash_alg_has_setkey);
+DEFINE_CRYPTO_API(crypto_shash_alg_has_setkey);
 
 static void shash_set_needkey(struct crypto_shash *tfm, struct shash_alg *alg)
 {
@@ -59,7 +59,7 @@ static void shash_set_needkey(struct crypto_shash *tfm, struct shash_alg *alg)
 		crypto_shash_set_flags(tfm, CRYPTO_TFM_NEED_KEY);
 }
 
-int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
+int CRYPTO_API(crypto_shash_setkey)(struct crypto_shash *tfm, const u8 *key,
 			unsigned int keylen)
 {
 	struct shash_alg *shash = crypto_shash_alg(tfm);
@@ -74,7 +74,7 @@ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
 	crypto_shash_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(crypto_shash_setkey);
+DEFINE_CRYPTO_API(crypto_shash_setkey);
 
 static int __crypto_shash_init(struct shash_desc *desc)
 {
@@ -90,13 +90,13 @@ static int __crypto_shash_init(struct shash_desc *desc)
 	return crypto_shash_alg(tfm)->init(desc);
 }
 
-int crypto_shash_init(struct shash_desc *desc)
+int CRYPTO_API(crypto_shash_init)(struct shash_desc *desc)
 {
 	if (crypto_shash_get_flags(desc->tfm) & CRYPTO_TFM_NEED_KEY)
 		return -ENOKEY;
 	return __crypto_shash_init(desc);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_init);
+DEFINE_CRYPTO_API(crypto_shash_init);
 
 static int shash_default_finup(struct shash_desc *desc, const u8 *data,
 			       unsigned int len, u8 *out)
@@ -119,7 +119,7 @@ static int crypto_shash_op_and_zero(
 	return err;
 }
 
-int crypto_shash_finup(struct shash_desc *restrict desc, const u8 *data,
+int CRYPTO_API(crypto_shash_finup)(struct shash_desc *restrict desc, const u8 *data,
 		       unsigned int len, u8 *restrict out)
 {
 	struct crypto_shash *tfm = desc->tfm;
@@ -183,7 +183,7 @@ int crypto_shash_finup(struct shash_desc *restrict desc, const u8 *data,
 	return crypto_shash_op_and_zero(crypto_shash_alg(tfm)->finup, desc,
 					data, len, out);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_finup);
+DEFINE_CRYPTO_API(crypto_shash_finup);
 
 static int shash_default_digest(struct shash_desc *desc, const u8 *data,
 				unsigned int len, u8 *out)
@@ -192,7 +192,7 @@ static int shash_default_digest(struct shash_desc *desc, const u8 *data,
 	       crypto_shash_finup(desc, data, len, out);
 }
 
-int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
+int CRYPTO_API(crypto_shash_digest)(struct shash_desc *desc, const u8 *data,
 			unsigned int len, u8 *out)
 {
 	struct crypto_shash *tfm = desc->tfm;
@@ -203,9 +203,9 @@ int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
 	return crypto_shash_op_and_zero(crypto_shash_alg(tfm)->digest, desc,
 					data, len, out);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_digest);
+DEFINE_CRYPTO_API(crypto_shash_digest);
 
-int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
+int CRYPTO_API(crypto_shash_tfm_digest)(struct crypto_shash *tfm, const u8 *data,
 			    unsigned int len, u8 *out)
 {
 	SHASH_DESC_ON_STACK(desc, tfm);
@@ -213,7 +213,7 @@ int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
 	desc->tfm = tfm;
 	return crypto_shash_digest(desc, data, len, out);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_tfm_digest);
+DEFINE_CRYPTO_API(crypto_shash_tfm_digest);
 
 static int __crypto_shash_export(struct shash_desc *desc, void *out,
 				 int (*export)(struct shash_desc *desc,
@@ -235,14 +235,14 @@ static int __crypto_shash_export(struct shash_desc *desc, void *out,
 	return export(desc, out);
 }
 
-int crypto_shash_export_core(struct shash_desc *desc, void *out)
+int CRYPTO_API(crypto_shash_export_core)(struct shash_desc *desc, void *out)
 {
 	return __crypto_shash_export(desc, out,
 				     crypto_shash_alg(desc->tfm)->export_core);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_export_core);
+DEFINE_CRYPTO_API(crypto_shash_export_core);
 
-int crypto_shash_export(struct shash_desc *desc, void *out)
+int CRYPTO_API(crypto_shash_export)(struct shash_desc *desc, void *out)
 {
 	struct crypto_shash *tfm = desc->tfm;
 
@@ -256,7 +256,7 @@ int crypto_shash_export(struct shash_desc *desc, void *out)
 	}
 	return __crypto_shash_export(desc, out, crypto_shash_alg(tfm)->export);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_export);
+DEFINE_CRYPTO_API(crypto_shash_export);
 
 static int __crypto_shash_import(struct shash_desc *desc, const void *in,
 				 int (*import)(struct shash_desc *desc,
@@ -284,14 +284,14 @@ static int __crypto_shash_import(struct shash_desc *desc, const void *in,
 	return import(desc, in);
 }
 
-int crypto_shash_import_core(struct shash_desc *desc, const void *in)
+int CRYPTO_API(crypto_shash_import_core)(struct shash_desc *desc, const void *in)
 {
 	return __crypto_shash_import(desc, in,
 				     crypto_shash_alg(desc->tfm)->import_core);
 }
-EXPORT_SYMBOL_GPL(crypto_shash_import_core);
+DEFINE_CRYPTO_API(crypto_shash_import_core);
 
-int crypto_shash_import(struct shash_desc *desc, const void *in)
+int CRYPTO_API(crypto_shash_import)(struct shash_desc *desc, const void *in)
 {
 	struct crypto_shash *tfm = desc->tfm;
 	int err;
@@ -309,7 +309,7 @@ int crypto_shash_import(struct shash_desc *desc, const void *in)
 	}
 	return err;
 }
-EXPORT_SYMBOL_GPL(crypto_shash_import);
+DEFINE_CRYPTO_API(crypto_shash_import);
 
 static void crypto_shash_exit_tfm(struct crypto_tfm *tfm)
 {
@@ -386,29 +386,29 @@ const struct crypto_type crypto_shash_type = {
 	.algsize = offsetof(struct shash_alg, base),
 };
 
-int crypto_grab_shash(struct crypto_shash_spawn *spawn,
+int CRYPTO_API(crypto_grab_shash)(struct crypto_shash_spawn *spawn,
 		      struct crypto_instance *inst,
 		      const char *name, u32 type, u32 mask)
 {
 	spawn->base.frontend = &crypto_shash_type;
 	return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
 }
-EXPORT_SYMBOL_GPL(crypto_grab_shash);
+DEFINE_CRYPTO_API(crypto_grab_shash);
 
-struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
+struct crypto_shash *CRYPTO_API(crypto_alloc_shash)(const char *alg_name, u32 type,
 					u32 mask)
 {
 	return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
 }
-EXPORT_SYMBOL_GPL(crypto_alloc_shash);
+DEFINE_CRYPTO_API(crypto_alloc_shash);
 
-int crypto_has_shash(const char *alg_name, u32 type, u32 mask)
+int CRYPTO_API(crypto_has_shash)(const char *alg_name, u32 type, u32 mask)
 {
 	return crypto_type_has_alg(alg_name, &crypto_shash_type, type, mask);
 }
-EXPORT_SYMBOL_GPL(crypto_has_shash);
+DEFINE_CRYPTO_API(crypto_has_shash);
 
-struct crypto_shash *crypto_clone_shash(struct crypto_shash *hash)
+struct crypto_shash *CRYPTO_API(crypto_clone_shash)(struct crypto_shash *hash)
 {
 	struct crypto_tfm *tfm = crypto_shash_tfm(hash);
 	struct shash_alg *alg = crypto_shash_alg(hash);
@@ -443,7 +443,7 @@ struct crypto_shash *crypto_clone_shash(struct crypto_shash *hash)
 
 	return nhash;
 }
-EXPORT_SYMBOL_GPL(crypto_clone_shash);
+DEFINE_CRYPTO_API(crypto_clone_shash);
 
 int hash_prepare_alg(struct hash_alg_common *alg)
 {
@@ -529,7 +529,7 @@ static int shash_prepare_alg(struct shash_alg *alg)
 	return 0;
 }
 
-int crypto_register_shash(struct shash_alg *alg)
+int CRYPTO_API(crypto_register_shash)(struct shash_alg *alg)
 {
 	struct crypto_alg *base = &alg->base;
 	int err;
@@ -540,15 +540,15 @@ int crypto_register_shash(struct shash_alg *alg)
 
 	return crypto_register_alg(base);
 }
-EXPORT_SYMBOL_GPL(crypto_register_shash);
+DEFINE_CRYPTO_API(crypto_register_shash);
 
-void crypto_unregister_shash(struct shash_alg *alg)
+void CRYPTO_API(crypto_unregister_shash)(struct shash_alg *alg)
 {
 	crypto_unregister_alg(&alg->base);
 }
-EXPORT_SYMBOL_GPL(crypto_unregister_shash);
+DEFINE_CRYPTO_API(crypto_unregister_shash);
 
-int crypto_register_shashes(struct shash_alg *algs, int count)
+int CRYPTO_API(crypto_register_shashes)(struct shash_alg *algs, int count)
 {
 	int i, ret;
 
@@ -566,18 +566,18 @@ int crypto_register_shashes(struct shash_alg *algs, int count)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(crypto_register_shashes);
+DEFINE_CRYPTO_API(crypto_register_shashes);
 
-void crypto_unregister_shashes(struct shash_alg *algs, int count)
+void CRYPTO_API(crypto_unregister_shashes)(struct shash_alg *algs, int count)
 {
 	int i;
 
 	for (i = count - 1; i >= 0; --i)
 		crypto_unregister_shash(&algs[i]);
 }
-EXPORT_SYMBOL_GPL(crypto_unregister_shashes);
+DEFINE_CRYPTO_API(crypto_unregister_shashes);
 
-int shash_register_instance(struct crypto_template *tmpl,
+int CRYPTO_API(shash_register_instance)(struct crypto_template *tmpl,
 			    struct shash_instance *inst)
 {
 	int err;
@@ -591,14 +591,14 @@ int shash_register_instance(struct crypto_template *tmpl,
 
 	return crypto_register_instance(tmpl, shash_crypto_instance(inst));
 }
-EXPORT_SYMBOL_GPL(shash_register_instance);
+DEFINE_CRYPTO_API(shash_register_instance);
 
-void shash_free_singlespawn_instance(struct shash_instance *inst)
+void CRYPTO_API(shash_free_singlespawn_instance)(struct shash_instance *inst)
 {
 	crypto_drop_spawn(shash_instance_ctx(inst));
 	kfree(inst);
 }
-EXPORT_SYMBOL_GPL(shash_free_singlespawn_instance);
+DEFINE_CRYPTO_API(shash_free_singlespawn_instance);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Synchronous cryptographic hash type");
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index c9d6ee97360e..3476f6209a22 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -765,12 +765,17 @@ static inline void ahash_request_set_virt(struct ahash_request *req,
  * Return: allocated cipher handle in case of success; IS_ERR() is true in case
  *	   of an error, PTR_ERR() returns the error code.
  */
-struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
-					u32 mask);
+DECLARE_CRYPTO_API(crypto_alloc_shash, struct crypto_shash *,
+	(const char *alg_name, u32 type, u32 mask),
+	(alg_name, type, mask));
 
-struct crypto_shash *crypto_clone_shash(struct crypto_shash *tfm);
+DECLARE_CRYPTO_API(crypto_clone_shash, struct crypto_shash *,
+	(struct crypto_shash *tfm),
+	(tfm));
 
-int crypto_has_shash(const char *alg_name, u32 type, u32 mask);
+DECLARE_CRYPTO_API(crypto_has_shash, int,
+	(const char *alg_name, u32 type, u32 mask),
+	(alg_name, type, mask));
 
 static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm)
 {
@@ -894,8 +899,9 @@ static inline void *shash_desc_ctx(struct shash_desc *desc)
  * Context: Softirq or process context.
  * Return: 0 if the setting of the key was successful; < 0 if an error occurred
  */
-int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
-			unsigned int keylen);
+DECLARE_CRYPTO_API(crypto_shash_setkey, int,
+	(struct crypto_shash *tfm, const u8 *key, unsigned int keylen),
+	(tfm, key, keylen));
 
 /**
  * crypto_shash_digest() - calculate message digest for buffer
@@ -912,8 +918,9 @@ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
  * Return: 0 if the message digest creation was successful; < 0 if an error
  *	   occurred
  */
-int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
-			unsigned int len, u8 *out);
+DECLARE_CRYPTO_API(crypto_shash_digest, int,
+	(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out),
+	(desc, data, len, out));
 
 /**
  * crypto_shash_tfm_digest() - calculate message digest for buffer
@@ -931,8 +938,9 @@ int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
  * Context: Softirq or process context.
  * Return: 0 on success; < 0 if an error occurred.
  */
-int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
-			    unsigned int len, u8 *out);
+DECLARE_CRYPTO_API(crypto_shash_tfm_digest, int,
+	(struct crypto_shash *tfm, const u8 *data, unsigned int len, u8 *out),
+	(tfm, data, len, out));
 
 DECLARE_CRYPTO_API(crypto_hash_digest, int,
 	(struct crypto_ahash *tfm, const u8 *data, unsigned int len, u8 *out),
@@ -950,7 +958,9 @@ DECLARE_CRYPTO_API(crypto_hash_digest, int,
  * Context: Softirq or process context.
  * Return: 0 if the export creation was successful; < 0 if an error occurred
  */
-int crypto_shash_export(struct shash_desc *desc, void *out);
+DECLARE_CRYPTO_API(crypto_shash_export, int,
+	(struct shash_desc *desc, void *out),
+	(desc, out));
 
 /**
  * crypto_shash_import() - import operational state
@@ -964,7 +974,9 @@ int crypto_shash_export(struct shash_desc *desc, void *out);
  * Context: Softirq or process context.
  * Return: 0 if the import was successful; < 0 if an error occurred
  */
-int crypto_shash_import(struct shash_desc *desc, const void *in);
+DECLARE_CRYPTO_API(crypto_shash_import, int,
+	(struct shash_desc *desc, const void *in),
+	(desc, in));
 
 /**
  * crypto_shash_init() - (re)initialize message digest
@@ -978,7 +990,9 @@ int crypto_shash_import(struct shash_desc *desc, const void *in);
  * Return: 0 if the message digest initialization was successful; < 0 if an
  *	   error occurred
  */
-int crypto_shash_init(struct shash_desc *desc);
+DECLARE_CRYPTO_API(crypto_shash_init, int,
+	(struct shash_desc *desc),
+	(desc));
 
 /**
  * crypto_shash_finup() - calculate message digest of buffer
@@ -995,8 +1009,9 @@ int crypto_shash_init(struct shash_desc *desc);
  * Return: 0 if the message digest creation was successful; < 0 if an error
  *	   occurred
  */
-int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
-		       unsigned int len, u8 *out);
+DECLARE_CRYPTO_API(crypto_shash_finup, int,
+	(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out),
+	(desc, data, len, out));
 
 /**
  * crypto_shash_update() - add data to message digest for processing
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
index c3f9ca511cf5..29b51abc1bad 100644
--- a/include/crypto/internal/hash.h
+++ b/include/crypto/internal/hash.h
@@ -107,7 +107,9 @@ DECLARE_CRYPTO_API(ahash_free_singlespawn_instance, void,
 	(struct ahash_instance *inst),
 	(inst));
 
-bool crypto_shash_alg_has_setkey(struct shash_alg *alg);
+DECLARE_CRYPTO_API(crypto_shash_alg_has_setkey, bool,
+	(struct shash_alg *alg),
+	(alg));
 
 DECLARE_CRYPTO_API(crypto_hash_alg_has_setkey, bool,
 	(struct hash_alg_common *halg),
@@ -146,17 +148,28 @@ static inline struct hash_alg_common *crypto_spawn_ahash_alg(
 	return __crypto_hash_alg_common(spawn->base.alg);
 }
 
-int crypto_register_shash(struct shash_alg *alg);
-void crypto_unregister_shash(struct shash_alg *alg);
-int crypto_register_shashes(struct shash_alg *algs, int count);
-void crypto_unregister_shashes(struct shash_alg *algs, int count);
-int shash_register_instance(struct crypto_template *tmpl,
-			    struct shash_instance *inst);
-void shash_free_singlespawn_instance(struct shash_instance *inst);
+DECLARE_CRYPTO_API(crypto_register_shash, int,
+	(struct shash_alg *alg),
+	(alg));
+DECLARE_CRYPTO_API(crypto_unregister_shash, void,
+	(struct shash_alg *alg),
+	(alg));
+DECLARE_CRYPTO_API(crypto_register_shashes, int,
+	(struct shash_alg *algs, int count),
+	(algs, count));
+DECLARE_CRYPTO_API(crypto_unregister_shashes, void,
+	(struct shash_alg *algs, int count),
+	(algs, count));
+DECLARE_CRYPTO_API(shash_register_instance, int,
+	(struct crypto_template *tmpl, struct shash_instance *inst),
+	(tmpl, inst));
+DECLARE_CRYPTO_API(shash_free_singlespawn_instance, void,
+	(struct shash_instance *inst),
+	(inst));
 
-int crypto_grab_shash(struct crypto_shash_spawn *spawn,
-		      struct crypto_instance *inst,
-		      const char *name, u32 type, u32 mask);
+DECLARE_CRYPTO_API(crypto_grab_shash, int,
+	(struct crypto_shash_spawn *spawn, struct crypto_instance *inst, const char *name, u32 type, u32 mask),
+	(spawn, inst, name, type, mask));
 
 static inline void crypto_drop_shash(struct crypto_shash_spawn *spawn)
 {
@@ -408,7 +421,9 @@ DECLARE_CRYPTO_API(crypto_ahash_import_core, int,
  * Context: Softirq or process context.
  * Return: 0 if the export creation was successful; < 0 if an error occurred
  */
-int crypto_shash_export_core(struct shash_desc *desc, void *out);
+DECLARE_CRYPTO_API(crypto_shash_export_core, int,
+	(struct shash_desc *desc, void *out),
+	(desc, out));
 
 /**
  * crypto_shash_import_core() - import core state
@@ -420,7 +435,9 @@ int crypto_shash_export_core(struct shash_desc *desc, void *out);
  * Context: Softirq or process context.
  * Return: 0 if the import was successful; < 0 if an error occurred
  */
-int crypto_shash_import_core(struct shash_desc *desc, const void *in);
+DECLARE_CRYPTO_API(crypto_shash_import_core, int,
+	(struct shash_desc *desc, const void *in),
+	(desc, in));
 
 #endif	/* _CRYPTO_INTERNAL_HASH_H */
 
-- 
2.39.3





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux