1 // SPDX-License-Identifier: GPL-2.0-only !! 1 /* GPL HEADER START >> 2 * >> 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >> 4 * >> 5 * This program is free software; you can redistribute it and/or modify >> 6 * it under the terms of the GNU General Public License version 2 only, >> 7 * as published by the Free Software Foundation. >> 8 * >> 9 * This program is distributed in the hope that it will be useful, but >> 10 * WITHOUT ANY WARRANTY; without even the implied warranty of >> 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> 12 * General Public License version 2 for more details (a copy is included >> 13 * in the LICENSE file that accompanied this code). >> 14 * >> 15 * You should have received a copy of the GNU General Public License >> 16 * version 2 along with this program; If not, see http://www.gnu.org/licenses >> 17 * >> 18 * Please visit http://www.xyratex.com/contact if you need additional >> 19 * information or have any questions. >> 20 * >> 21 * GPL HEADER END >> 22 */ >> 23 2 /* 24 /* 3 * Copyright 2012 Xyratex Technology Limited 25 * Copyright 2012 Xyratex Technology Limited 4 */ 26 */ 5 27 6 /* 28 /* 7 * This is crypto api shash wrappers to crc32_ 29 * This is crypto api shash wrappers to crc32_le. 8 */ 30 */ 9 31 10 #include <linux/unaligned.h> !! 32 #include <asm/unaligned.h> 11 #include <linux/crc32.h> 33 #include <linux/crc32.h> 12 #include <crypto/internal/hash.h> 34 #include <crypto/internal/hash.h> 13 #include <linux/init.h> 35 #include <linux/init.h> 14 #include <linux/module.h> 36 #include <linux/module.h> 15 #include <linux/string.h> 37 #include <linux/string.h> 16 #include <linux/kernel.h> 38 #include <linux/kernel.h> 17 39 18 #define CHKSUM_BLOCK_SIZE 1 40 #define CHKSUM_BLOCK_SIZE 1 19 #define CHKSUM_DIGEST_SIZE 4 41 #define CHKSUM_DIGEST_SIZE 4 20 42 21 /** No default init with ~0 */ 43 /** No default init with ~0 */ 22 static int crc32_cra_init(struct crypto_tfm *t 44 static int crc32_cra_init(struct crypto_tfm *tfm) 23 { 45 { 24 u32 *key = crypto_tfm_ctx(tfm); 46 u32 *key = crypto_tfm_ctx(tfm); 25 47 26 *key = 0; 48 *key = 0; 27 49 28 return 0; 50 return 0; 29 } 51 } 30 52 31 /* 53 /* 32 * Setting the seed allows arbitrary accumulat 54 * Setting the seed allows arbitrary accumulators and flexible XOR policy 33 * If your algorithm starts with ~0, then XOR 55 * If your algorithm starts with ~0, then XOR with ~0 before you set 34 * the seed. 56 * the seed. 35 */ 57 */ 36 static int crc32_setkey(struct crypto_shash *h 58 static int crc32_setkey(struct crypto_shash *hash, const u8 *key, 37 unsigned int keylen) 59 unsigned int keylen) 38 { 60 { 39 u32 *mctx = crypto_shash_ctx(hash); 61 u32 *mctx = crypto_shash_ctx(hash); 40 62 41 if (keylen != sizeof(u32)) !! 63 if (keylen != sizeof(u32)) { >> 64 crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN); 42 return -EINVAL; 65 return -EINVAL; >> 66 } 43 *mctx = get_unaligned_le32(key); 67 *mctx = get_unaligned_le32(key); 44 return 0; 68 return 0; 45 } 69 } 46 70 47 static int crc32_init(struct shash_desc *desc) 71 static int crc32_init(struct shash_desc *desc) 48 { 72 { 49 u32 *mctx = crypto_shash_ctx(desc->tfm 73 u32 *mctx = crypto_shash_ctx(desc->tfm); 50 u32 *crcp = shash_desc_ctx(desc); 74 u32 *crcp = shash_desc_ctx(desc); 51 75 52 *crcp = *mctx; 76 *crcp = *mctx; 53 77 54 return 0; 78 return 0; 55 } 79 } 56 80 57 static int crc32_update(struct shash_desc *des 81 static int crc32_update(struct shash_desc *desc, const u8 *data, 58 unsigned int len) 82 unsigned int len) 59 { 83 { 60 u32 *crcp = shash_desc_ctx(desc); 84 u32 *crcp = shash_desc_ctx(desc); 61 85 62 *crcp = crc32_le(*crcp, data, len); 86 *crcp = crc32_le(*crcp, data, len); 63 return 0; 87 return 0; 64 } 88 } 65 89 66 /* No final XOR 0xFFFFFFFF, like crc32_le */ 90 /* No final XOR 0xFFFFFFFF, like crc32_le */ 67 static int __crc32_finup(u32 *crcp, const u8 * 91 static int __crc32_finup(u32 *crcp, const u8 *data, unsigned int len, 68 u8 *out) 92 u8 *out) 69 { 93 { 70 put_unaligned_le32(crc32_le(*crcp, dat 94 put_unaligned_le32(crc32_le(*crcp, data, len), out); 71 return 0; 95 return 0; 72 } 96 } 73 97 74 static int crc32_finup(struct shash_desc *desc 98 static int crc32_finup(struct shash_desc *desc, const u8 *data, 75 unsigned int len, u8 *o 99 unsigned int len, u8 *out) 76 { 100 { 77 return __crc32_finup(shash_desc_ctx(de 101 return __crc32_finup(shash_desc_ctx(desc), data, len, out); 78 } 102 } 79 103 80 static int crc32_final(struct shash_desc *desc 104 static int crc32_final(struct shash_desc *desc, u8 *out) 81 { 105 { 82 u32 *crcp = shash_desc_ctx(desc); 106 u32 *crcp = shash_desc_ctx(desc); 83 107 84 put_unaligned_le32(*crcp, out); 108 put_unaligned_le32(*crcp, out); 85 return 0; 109 return 0; 86 } 110 } 87 111 88 static int crc32_digest(struct shash_desc *des 112 static int crc32_digest(struct shash_desc *desc, const u8 *data, 89 unsigned int len, u8 * 113 unsigned int len, u8 *out) 90 { 114 { 91 return __crc32_finup(crypto_shash_ctx( 115 return __crc32_finup(crypto_shash_ctx(desc->tfm), data, len, 92 out); 116 out); 93 } 117 } 94 static struct shash_alg alg = { 118 static struct shash_alg alg = { 95 .setkey = crc32_setkey, 119 .setkey = crc32_setkey, 96 .init = crc32_init, 120 .init = crc32_init, 97 .update = crc32_update, 121 .update = crc32_update, 98 .final = crc32_final, 122 .final = crc32_final, 99 .finup = crc32_finup, 123 .finup = crc32_finup, 100 .digest = crc32_digest, 124 .digest = crc32_digest, 101 .descsize = sizeof(u32), 125 .descsize = sizeof(u32), 102 .digestsize = CHKSUM_DIGEST_SIZE, 126 .digestsize = CHKSUM_DIGEST_SIZE, 103 .base = { 127 .base = { 104 .cra_name = "crc 128 .cra_name = "crc32", 105 .cra_driver_name = "crc 129 .cra_driver_name = "crc32-generic", 106 .cra_priority = 100, 130 .cra_priority = 100, 107 .cra_flags = CRYP 131 .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, 108 .cra_blocksize = CHKS 132 .cra_blocksize = CHKSUM_BLOCK_SIZE, 109 .cra_ctxsize = size 133 .cra_ctxsize = sizeof(u32), 110 .cra_module = THIS 134 .cra_module = THIS_MODULE, 111 .cra_init = crc3 135 .cra_init = crc32_cra_init, 112 } 136 } 113 }; 137 }; 114 138 115 static int __init crc32_mod_init(void) 139 static int __init crc32_mod_init(void) 116 { 140 { 117 return crypto_register_shash(&alg); 141 return crypto_register_shash(&alg); 118 } 142 } 119 143 120 static void __exit crc32_mod_fini(void) 144 static void __exit crc32_mod_fini(void) 121 { 145 { 122 crypto_unregister_shash(&alg); 146 crypto_unregister_shash(&alg); 123 } 147 } 124 148 125 subsys_initcall(crc32_mod_init); 149 subsys_initcall(crc32_mod_init); 126 module_exit(crc32_mod_fini); 150 module_exit(crc32_mod_fini); 127 151 128 MODULE_AUTHOR("Alexander Boyko <alexander_boyk 152 MODULE_AUTHOR("Alexander Boyko <alexander_boyko@xyratex.com>"); 129 MODULE_DESCRIPTION("CRC32 calculations wrapper 153 MODULE_DESCRIPTION("CRC32 calculations wrapper for lib/crc32"); 130 MODULE_LICENSE("GPL"); 154 MODULE_LICENSE("GPL"); 131 MODULE_ALIAS_CRYPTO("crc32"); 155 MODULE_ALIAS_CRYPTO("crc32"); 132 MODULE_ALIAS_CRYPTO("crc32-generic"); 156 MODULE_ALIAS_CRYPTO("crc32-generic"); 133 157
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.