📄 cipher.c
字号:
/* * GNU POC (passwords on card) - manage passwords on smartcards * Copyright (C) 2001 Henning Koester <henning@crackinghacking.de> * * Please report bugs to bug-poc@gnu.org * * This file is part of POC. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* $Id: cipher.c,v 1.9 2001/08/18 16:09:21 henning Exp $ */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#ifdef HAVE_BYTESWAP_H#include <byteswap.h>#else#include "missing_libs.h"#endif#include "poc.h"#include "poc_types.h"#include "poc_macros.h"#include "cipher.h"#include "lang.h"#include "misc.h"#include "iv.h"/* Ciphers */#include "rijndael.h"#include "blowfish.h"/* Hashes */#include "tiger.h"#include "sha2.h"static BLOWFISH_context blowfish_ctx;static RIJNDAEL_context rijndael_ctx;/****************************************************************************** * * Function : cipher_setkey * * Description : This function calls the cipher's key-schedule function, which * expands the hashed key for the cipher's needs. * * Input : [1] card_crypt_ctx (crypt_context) * Information about data encryption (cipher, security-level) * [2] key (u8) * Raw key as it was entered by the user. * [3] key_bytes (int) * Key length in byte. * * Return : POC_ERROR or POC_SUCCESS * *****************************************************************************/bool cipher_setkey(const crypt_context * const card_crypt_ctx, const u8 * const key, const int key_bytes) { u8 *hashed_key = NULL; /* The hashed key. */ int needed_key_bits = 0; /* How much key-bits are needed for en/decryption*/ u64 *bit64_ptr; /* Used for byte-swap. */ /* Setup the key sizes based on the security-level. */ if (card_crypt_ctx->sec_level == SL_NORMAL) needed_key_bits = 192; /* Normal. */ else /* else SL_HIGH */ needed_key_bits = 256; /* High. */ /* Allocate memory for the hashed key. */ if ( (hashed_key = realloc(hashed_key, (needed_key_bits / 8))) == NULL) { print_err(ERR_PRFX_NM); perror(""); return(POC_ERROR); } /* * Hash the key by calling the appropriate hashing function. For high * security we will call SHA256 because we use a 256 bit key for high * security. And for normal security we will use Tiger, to get a 192 bit * hash. */ if (needed_key_bits == 256) { { SHA256_CTX context; SHA256_Init(&context); SHA256_Update(&context, key, key_bytes); SHA256_Final(hashed_key, &context); }; } else { bit64_ptr = (u64 *) hashed_key; tiger((u8 *) key, key_bytes, bit64_ptr); bit64_ptr[0] = bswap_64(bit64_ptr[0]); bit64_ptr[1] = bswap_64(bit64_ptr[1]); bit64_ptr[2] = bswap_64(bit64_ptr[2]); }#ifdef DEBUG { int i; for (i = 0; i < needed_key_bits / 8; i++) printf("%02X", hashed_key[i]); printf("\n"); };#endif /* Call the cipher's key-scheduleing function. */ if (strcmp(card_crypt_ctx->cipher, "AES") == 0) rijndael_setkey(&rijndael_ctx, hashed_key, needed_key_bits / 8); else if (strcmp(card_crypt_ctx->cipher, "BLOWFISH") == 0) bf_setkey(&blowfish_ctx, hashed_key, needed_key_bits / 8); return(POC_SUCCESS);}/****************************************************************************** * * Function : encrypt_data * * Description : This function en/decrypts a buffer in OFB mode, using the * encryption function to which 'algo_func' points to. * * Input : [1] algo_func (void) * Pointer to a function, which will be used for data en- * cryption. * [2] algo_block_length * The cipher's block size. * [3] algo_ctx (void) * The cipher's context, which holds key material. * [4] buffer (u8) * The data, which will be en/decrypted. * [5] bytes (int) * How much bytes will be en/decrypted. * [6] iv (u8) * Initialization vector (see iv.h) * * Return : nothing is returned * *****************************************************************************/static voidencrypt_data(void (*algo_func)(), int algo_block_length, void *algo_ctx, u8 * const buffer, int bytes, u8 * const iv) { unsigned short int i, j; /* Counters. */ /* * The first byte which is the description tag 0x80 will not be encrypted. * Hence we substract 1 from 'bytes'. */ bytes--; /* * OFB en/decryption. * Take a look at doc/OFB to get to know how the OFB mode works. */ for (i = 0; i < bytes; i += algo_block_length) { (*algo_func)(algo_ctx, iv, iv); for (j = 0; j < algo_block_length; j++) { if (i + j == bytes) return; buffer[j + i + 1] ^= iv[j]; } }}/****************************************************************************** * * Function : cipher_ofb * * Description : This function calls 'encrypt_data' with the appropriate * arguments. * * Input : [1] card_crypt_ctx * Information about data encryption (cipher, security-level) * [2] buffer (u8) * The data which will be en/decrypted. * [3] bytes (int) * Number of bytes in buffer. * * Return : nothing is returned * *****************************************************************************/void cipher_ofb(const crypt_context * const card_crypt_ctx, u8 * const buffer, int bytes) { u8 iv[] = IV; /* Initialization vector. (see iv.h and doc/OFB). */ /* * Check which cipher we shall use and call 'encrypt_data' with appropriate * arguments. */ if (strcmp(card_crypt_ctx->cipher, "AES") == 0) encrypt_data(rijndael_encrypt, 16, &rijndael_ctx, buffer, bytes, iv); else if (strcmp(card_crypt_ctx->cipher, "BLOWFISH") == 0) encrypt_data(blowfish_encrypt, 8, &blowfish_ctx, buffer, bytes, iv);}/****************************************************************************** * * Function : cipher_wipe * * Description : This function wipes sensetive data, like key material. * * Input : [1] card_crypt_ctx * Information about data encryption (cipher, security-level) * * Return : nothing is returned * *****************************************************************************/void cipher_wipe(const crypt_context * const card_crypt_ctx) { /* Which cipher has been used? */ if (strcmp(card_crypt_ctx->cipher, "AES") == 0) rijndael_wipe(&rijndael_ctx); else if (strcmp(card_crypt_ctx->cipher, "BLOWFISH") == 0) blowfish_wipe(&blowfish_ctx);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -