📄 cipher-rc5.c
字号:
/* $Id: cipher-rc5.c,v 1.14 2002/10/01 23:14:14 hvr Exp $ * * rc5.c RC5-32/[12,16]/b * * Copyright (c) 1999 Pekka Riikonen <priikone@poseidon.pspt.fi> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, dis- * tribute, sublicense, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do so, subject to the fol- * lowing conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL- * ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Except as contained in this notice, the name of the authors shall * not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * the authors. * * This cipher is patented, and is free for educational usage. For * commercial use, please contact RSA Security, Inc. * */#include <linux/module.h>#include <linux/errno.h> #include <linux/init.h> #include <linux/string.h> #include <linux/crypto.h> #include <linux/wordops.h> #ifdef MODULE_LICENSEMODULE_LICENSE("Dual BSD/GPL");#endif#ifdef MODULE_DESCRIPTIONMODULE_DESCRIPTION ("RC5 Cipher / CryptoAPI");#endif#ifdef MODULE_AUTHORMODULE_AUTHOR ("Pekka Riikonen <priikone@poseidon.pspt.fi>");#endif/* 12 rounds for testing, 16 rounds for use */#ifdef CRYPTOAPI_TEST #define ROUNDS 12#else #define ROUNDS 16#endif /* CRYPTOAPI_TEST *//* RC5 definitions */#define W 32 /* word size, in bits */#define MIN_KEY 16 /* minimum key size in bytes */#define C 8 /* same for 128, 192 and 256 bits key */#define TABSIZE (2 *(ROUNDS + 1)) /* size of S table, t = 2 * (r + 1) */#define rotl generic_rotl32#define rotr generic_rotr32/* RC5 encryption */#define RC5E(i, A, B, S) do { \ A = A ^ B; \ A = rotl(A, B) + S[i]; \ B = B ^ A; \ B = rotl(B, A) + S[i + 1]; \ } while(0); /* RC5 decryption */#define RC5D(i, A, B, S) do { \ B = B - S[i + 1]; \ B = rotr(B, A) ^ A; \ A = A - S[i]; \ A = rotr(A, B) ^ B; \ } while(0);struct rc5_ctx { u32 xk[TABSIZE];};/* Sets RC5 key */static intrc5_set_key(struct cipher_context *cx, const u8 *key, int key_len, int atomic){ struct rc5_ctx *ctx; const u32 *in_key = (const u32 *)key; u32 i, j, k, A, B, L[C], c; ctx = (struct rc5_ctx *) cx->keyinfo; if (key_len != 16 && key_len != 24 && key_len != 32) return -EINVAL; /* unsupported key length */ cx->key_length = key_len; key_len *= 8; c = key_len / W; /* init L */ for (i = 0; i < C; i++) { L[i] = 0; } for (i = 0; i < (key_len / W); i++) { L[i] = le32_to_cpu (in_key[i]); } /* initialize expanded key array */ ctx->xk[0] = 0xb7e15163; for (i = 1; i < TABSIZE; i++) { ctx->xk[i] = ctx->xk[i - 1] + 0x9e3779b9; } /* mix L and key array (S) */ A = B = 0; i = j = 0; for (k = 0; k < (3 * TABSIZE); k++) { A = ctx->xk[i] = rotl(ctx->xk[i] + A + B, 3); B = L[j] = rotl(L[j] + (A + B), A + B); i = (i + 1) % TABSIZE; j = (j + 1) % c; } return 0;}/* Encrypts *one* block at a time. */static intrc5_encrypt(struct cipher_context *cx, const u8 *in8, u8 *out8, int size, int atomic){ const struct rc5_ctx *ctx = (struct rc5_ctx *) cx->keyinfo; const u32 *in = (const u32 *)in8; u32 *out = (u32 *)out8; u32 A = le32_to_cpu (in[0]) + ctx->xk[0]; u32 B = le32_to_cpu (in[1]) + ctx->xk[1]; int i; for (i = 1; i <= ROUNDS; i++) { RC5E(i * 2, A, B, ctx->xk); } out[0] = cpu_to_le32 (A); out[1] = cpu_to_le32 (B); return 0;}/* Decrypts *one* block at a time. */static intrc5_decrypt(struct cipher_context *cx, const u8 *in8, u8 *out8, int size, int atomic){ const struct rc5_ctx *ctx = (struct rc5_ctx *) cx->keyinfo; const u32 *in = (u32 *)in8; u32 *out = (u32 *)out8; u32 A = le32_to_cpu (in[0]); u32 B = le32_to_cpu (in[1]); int i; for (i = ROUNDS; i >= 1; i--) { RC5D(i * 2, A, B, ctx->xk); } out[0] = cpu_to_le32 (A - ctx->xk[0]); out[1] = cpu_to_le32 (B - ctx->xk[1]); return 0;} #define CIPHER_ID rc5#define CIPHER_BLOCKSIZE 64#define CIPHER_KEY_SIZE_MASK CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | \ CIPHER_KEYSIZE_256#define CIPHER_KEY_SCHEDULE_SIZE sizeof(struct rc5_ctx)#include "gen-cipher.h"EXPORT_NO_SYMBOLS;/* eof */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -