commit
b6b0eeb7b8
@ -0,0 +1,162 @@ |
||||
|
||||
#include <stdio.h> |
||||
#include <vector> |
||||
#include "bch.h" |
||||
/*
|
||||
* Copyright 2010, KA1RBI
|
||||
*/ |
||||
static const int bchGFexp[64] = { |
||||
1, 2, 4, 8, 16, 32, 3, 6, 12, 24, 48, 35, 5, 10, 20, 40, |
||||
19, 38, 15, 30, 60, 59, 53, 41, 17, 34, 7, 14, 28, 56, 51, 37, |
||||
9, 18, 36, 11, 22, 44, 27, 54, 47, 29, 58, 55, 45, 25, 50, 39, |
||||
13, 26, 52, 43, 21, 42, 23, 46, 31, 62, 63, 61, 57, 49, 33, 0 |
||||
}; |
||||
|
||||
static const int bchGFlog[64] = { |
||||
-1, 0, 1, 6, 2, 12, 7, 26, 3, 32, 13, 35, 8, 48, 27, 18, |
||||
4, 24, 33, 16, 14, 52, 36, 54, 9, 45, 49, 38, 28, 41, 19, 56, |
||||
5, 62, 25, 11, 34, 31, 17, 47, 15, 23, 53, 51, 37, 44, 55, 40, |
||||
10, 61, 46, 30, 50, 22, 39, 43, 29, 60, 42, 21, 20, 59, 57, 58 |
||||
}; |
||||
|
||||
static const int bchG[48] = { |
||||
1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, |
||||
1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, |
||||
1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1 |
||||
}; |
||||
|
||||
int bchDec(bit_vector& Codeword) |
||||
{ |
||||
|
||||
int elp[24][ 22], S[23]; |
||||
int D[23], L[24], uLu[24]; |
||||
int root[11], locn[11], reg[12]; |
||||
int i,j,U,q,count; |
||||
int SynError, CantDecode; |
||||
|
||||
SynError = 0; CantDecode = 0; |
||||
|
||||
for(i = 1; i <= 22; i++) { |
||||
S[i] = 0; |
||||
// FOR j = 0 TO 62
|
||||
for(j = 0; j <= 62; j++) { |
||||
if( Codeword[j]) { S[i] = S[i] ^ bchGFexp[(i * j) % 63]; } |
||||
} |
||||
if( S[i]) { SynError = 1; } |
||||
S[i] = bchGFlog[S[i]]; |
||||
// printf("S[%d] %d\n", i, S[i]);
|
||||
} |
||||
|
||||
if( SynError) { //if there are errors, try to correct them
|
||||
L[0] = 0; uLu[0] = -1; D[0] = 0; elp[0][ 0] = 0; |
||||
L[1] = 0; uLu[1] = 0; D[1] = S[1]; elp[1][ 0] = 1; |
||||
//FOR i = 1 TO 21
|
||||
for(i = 1; i <= 21; i++) { |
||||
elp[0][ i] = -1; elp[1][ i] = 0; |
||||
} |
||||
U = 0; |
||||
|
||||
do { |
||||
U = U + 1; |
||||
if( D[U] == -1) { |
||||
L[U + 1] = L[U]; |
||||
// FOR i = 0 TO L[U]
|
||||
for(i = 0; i <= L[U]; i++) { |
||||
elp[U + 1][ i] = elp[U][ i]; elp[U][ i] = bchGFlog[elp[U][ i]]; |
||||
} |
||||
} else { |
||||
//search for words with greatest uLu(q) for which d(q)!=0
|
||||
q = U - 1; |
||||
while((D[q] == -1) &&(q > 0)) { q = q - 1; } |
||||
//have found first non-zero d(q)
|
||||
if( q > 0) { |
||||
j = q; |
||||
do { j = j - 1; if((D[j] != -1) &&(uLu[q] < uLu[j])) { q = j; } |
||||
} while( j > 0) ; |
||||
} |
||||
|
||||
//store degree of new elp polynomial
|
||||
if( L[U] > L[q] + U - q) { |
||||
L[U + 1] = L[U] ; |
||||
} else { |
||||
L[U + 1] = L[q] + U - q; |
||||
} |
||||
|
||||
///* form new elp(x) */
|
||||
// FOR i = 0 TO 21
|
||||
for(i = 0; i <= 21; i++) { |
||||
elp[U + 1][ i] = 0; |
||||
} |
||||
// FOR i = 0 TO L(q)
|
||||
for(i = 0; i <= L[q]; i++) { |
||||
if( elp[q][ i] != -1) { |
||||
elp[U + 1][ i + U - q] = bchGFexp[(D[U] + 63 - D[q] + elp[q][ i]) % 63]; |
||||
} |
||||
} |
||||
// FOR i = 0 TO L(U)
|
||||
for(i = 0; i <= L[U]; i++) { |
||||
elp[U + 1][ i] = elp[U + 1][ i] ^ elp[U][ i]; |
||||
elp[U][ i] = bchGFlog[elp[U][ i]]; |
||||
} |
||||
} |
||||
uLu[U + 1] = U - L[U + 1]; |
||||
|
||||
//form(u+1)th discrepancy
|
||||
if( U < 22) { |
||||
//no discrepancy computed on last iteration
|
||||
if( S[U + 1] != -1) { D[U + 1] = bchGFexp[S[U + 1]]; } else { D[U + 1] = 0; } |
||||
// FOR i = 1 TO L(U + 1)
|
||||
for(i = 1; i <= L[U + 1]; i++) { |
||||
if((S[U + 1 - i] != -1) &&(elp[U + 1][ i] != 0)) { |
||||
D[U + 1] = D[U + 1] ^ bchGFexp[(S[U + 1 - i] + bchGFlog[elp[U + 1][ i]]) % 63]; |
||||
} |
||||
} |
||||
//put d(u+1) into index form */
|
||||
D[U + 1] = bchGFlog[D[U + 1]]; |
||||
} |
||||
} while((U < 22) &&(L[U + 1] <= 11)); |
||||
|
||||
U = U + 1; |
||||
if( L[U] <= 11) { // /* Can correct errors */
|
||||
//put elp into index form
|
||||
// FOR i = 0 TO L[U]
|
||||
for(i = 0; i <= L[U]; i++) { |
||||
elp[U][ i] = bchGFlog[elp[U][ i]]; |
||||
} |
||||
|
||||
//Chien search: find roots of the error location polynomial
|
||||
// FOR i = 1 TO L(U)
|
||||
for(i = 1; i <= L[U]; i++) { |
||||
reg[i] = elp[U][ i]; |
||||
} |
||||
count = 0; |
||||
// FOR i = 1 TO 63
|
||||
for(i = 1; i <= 63; i++) { |
||||
q = 1; |
||||
//FOR j = 1 TO L(U)
|
||||
for(j = 1; j <= L[U]; j++) { |
||||
if( reg[j] != -1) { |
||||
reg[j] =(reg[j] + j) % 63; q = q ^ bchGFexp[reg[j]]; |
||||
} |
||||
} |
||||
if( q == 0) { //store root and error location number indices
|
||||
root[count] = i; locn[count] = 63 - i; count = count + 1; |
||||
} |
||||
} |
||||
if( count == L[U]) { |
||||
//no. roots = degree of elp hence <= t errors
|
||||
//FOR i = 0 TO L[U] - 1
|
||||
for(i = 0; i <= L[U]-1; i++) { |
||||
Codeword[locn[i]] = Codeword[locn[i]] ^ 1; |
||||
} |
||||
CantDecode = count; |
||||
} else { //elp has degree >t hence cannot solve
|
||||
CantDecode = -1; |
||||
} |
||||
} else { |
||||
CantDecode = -2; |
||||
} |
||||
} |
||||
return CantDecode; |
||||
} |
||||
|
@ -0,0 +1,4 @@ |
||||
#include <vector> |
||||
typedef std::vector<bool> bit_vector; |
||||
int bchDec(bit_vector& Codeword); |
||||
|
@ -0,0 +1,286 @@ |
||||
#include "crypto.h" |
||||
|
||||
#include <sstream> |
||||
#include <boost/format.hpp> |
||||
#include <iostream> |
||||
#include <stdio.h> |
||||
#include <memory.h> |
||||
|
||||
extern "C" { |
||||
#include "des.h" |
||||
} |
||||
|
||||
static unsigned long long swap_bytes(uint64_t l) |
||||
{ |
||||
unsigned long long r; |
||||
unsigned char* pL = (unsigned char*)&l; |
||||
unsigned char* pR = (unsigned char*)&r; |
||||
for (int i = 0; i < sizeof(l); ++i) |
||||
pR[i] = pL[(sizeof(l) - 1) - i]; |
||||
return r; |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
class null_algorithm : public crypto_algorithm // This is an algorithm skeleton (can be used for no encryption as pass-through)
|
||||
{ |
||||
private: |
||||
size_t m_generated_bits; |
||||
public: |
||||
null_algorithm() |
||||
: m_generated_bits(0) |
||||
{ |
||||
} |
||||
const type_id id() const |
||||
{ |
||||
return crypto_algorithm::NONE; |
||||
} |
||||
bool update(const struct CryptoState& state) |
||||
{ |
||||
fprintf(stderr, "NULL:\t%d bits generated\n", m_generated_bits); |
||||
|
||||
m_generated_bits = 0; |
||||
|
||||
return true; |
||||
} |
||||
bool set_key(const crypto_algorithm::key_type& key) |
||||
{ |
||||
return true; |
||||
} |
||||
uint64_t generate(size_t n) |
||||
{ |
||||
m_generated_bits += n; |
||||
return 0; |
||||
} |
||||
}; |
||||
*/ |
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class des_ofb : public crypto_algorithm |
||||
{ |
||||
public: |
||||
unsigned long long m_key_des, m_next_iv, m_ks; |
||||
int m_ks_idx; |
||||
DES_KS m_ksDES; |
||||
int m_iterations; |
||||
uint16_t m_current_kid; |
||||
key_type m_default_key; |
||||
key_map_type m_key_map; |
||||
bool m_verbose; |
||||
public: |
||||
des_ofb() |
||||
: m_current_kid(-1) |
||||
{ |
||||
memset(&m_ksDES, 0, sizeof(m_ksDES)); |
||||
m_key_des = 0; |
||||
m_next_iv = 0; |
||||
m_ks_idx = 0; |
||||
m_ks = 0; |
||||
m_iterations = 0; |
||||
} |
||||
|
||||
void set_logging(bool on) |
||||
{ |
||||
m_verbose = on; |
||||
} |
||||
|
||||
const type_id id() const |
||||
{ |
||||
return crypto_algorithm::DES_OFB; |
||||
} |
||||
|
||||
bool update(const struct CryptoState& state) |
||||
{ |
||||
if (m_current_kid != state.kid) |
||||
{ |
||||
if (m_key_map.empty()) |
||||
{ |
||||
// Nothing to do
|
||||
} |
||||
else |
||||
{ |
||||
key_map_type::iterator it = m_key_map.find(state.kid); |
||||
if (it != m_key_map.end()) |
||||
{ |
||||
set_key(it->second); |
||||
} |
||||
else if (!m_default_key.empty()) |
||||
{ |
||||
/*if (m_verbose) */fprintf(stderr, "Key 0x%04x not found in key map - using default key\n", state.kid); |
||||
|
||||
set_key(m_default_key); |
||||
} |
||||
else |
||||
{ |
||||
/*if (m_verbose) */fprintf(stderr, "Key 0x%04x not found in key map and no default key\n", state.kid); |
||||
} |
||||
} |
||||
|
||||
m_current_kid = state.kid; |
||||
} |
||||
|
||||
uint64_t iv = 0; |
||||
size_t n = std::min(sizeof(iv), state.mi.size()); |
||||
memcpy(&iv, &state.mi[0], n); |
||||
set_iv(iv); |
||||
|
||||
return (n == 8); |
||||
} |
||||
|
||||
void set_key_map(const key_map_type& key_map) |
||||
{ |
||||
m_key_map = key_map; |
||||
|
||||
m_current_kid = -1; // To refresh on next update if it has changed
|
||||
} |
||||
|
||||
bool set_key(const crypto_algorithm::key_type& key) |
||||
{ |
||||
const size_t valid_key_length = 8; |
||||
|
||||
if (key.size() != valid_key_length) |
||||
{ |
||||
if (m_verbose) fprintf(stderr, "DES:\tIncorrect key length of %lu (should be %lu)\n", key.size(), valid_key_length); |
||||
return false; |
||||
} |
||||
|
||||
m_default_key = key; |
||||
|
||||
memcpy(&m_key_des, &key[0], std::min(key.size(), sizeof(m_key_des))); |
||||
|
||||
if (m_verbose) |
||||
{ |
||||
std::stringstream ss; |
||||
for (int i = 0; i < valid_key_length; ++i) |
||||
ss << boost::format("%02X") % (int)key[i]; |
||||
std::cerr << "DES:\tKey: " << ss.str() << std::endl; |
||||
} |
||||
|
||||
deskey(m_ksDES, (unsigned char*)&m_key_des, 0); // 0: encrypt (for OFB mode)
|
||||
|
||||
return true; |
||||
} |
||||
|
||||
void set_iv(uint64_t iv) |
||||
{ |
||||
if (m_iterations > 0) |
||||
{ |
||||
if (m_verbose) fprintf(stderr, "DES:\t%i bits used from %i iterations\n", m_ks_idx, m_iterations); |
||||
} |
||||
|
||||
m_next_iv = iv; |
||||
|
||||
m_ks_idx = 0; |
||||
m_iterations = 0; |
||||
|
||||
m_ks = m_next_iv; |
||||
des(m_ksDES, (unsigned char*)&m_ks); // First initialisation
|
||||
++m_iterations; |
||||
|
||||
des(m_ksDES, (unsigned char*)&m_ks); // Throw out first iteration & prepare for second
|
||||
++m_iterations; |
||||
|
||||
generate(64); // Reserved 3 + first 5 of LC (3 left)
|
||||
generate(3 * 8); // Use remaining 3 bytes for LC
|
||||
} |
||||
|
||||
uint64_t generate(size_t count) // 1..64
|
||||
{ |
||||
unsigned long long ullCurrent = swap_bytes(m_ks); |
||||
const int max_len = 64; |
||||
int pos = m_ks_idx % max_len; |
||||
|
||||
m_ks_idx += count; |
||||
|
||||
if ((pos + count) <= max_len) // Up to 64
|
||||
{ |
||||
if ((m_ks_idx % max_len) == 0) |
||||
{ |
||||
des(m_ksDES, (unsigned char*)&m_ks); // Prepare for next iteration
|
||||
++m_iterations; |
||||
} |
||||
|
||||
unsigned long long result = (ullCurrent >> (((max_len - 1) - pos) - (count-1))) & ((count == max_len) ? (unsigned long long)-1 : ((1ULL << count) - 1)); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
// Over-flow 64-bit boundary (so all of rest of current will be used)
|
||||
|
||||
des(m_ksDES, (unsigned char*)&m_ks); // Compute second part
|
||||
++m_iterations; |
||||
|
||||
unsigned long long first = ullCurrent << pos; // RHS will be zeros
|
||||
|
||||
ullCurrent = swap_bytes(m_ks); |
||||
int remainder = count - (max_len - pos); |
||||
first >>= (((max_len - 1) - remainder) - ((max_len - 1) - pos)); |
||||
unsigned long long next = (ullCurrent >> (((max_len - 1) - 0) - (remainder-1))) & ((1ULL << remainder) - 1); |
||||
|
||||
return (first | next); |
||||
} |
||||
|
||||
}; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
crypto_module::crypto_module(bool verbose/* = true*/) |
||||
: d_verbose(verbose) |
||||
{ |
||||
} |
||||
|
||||
crypto_algorithm::sptr crypto_module::algorithm(crypto_algorithm::type_id algid) |
||||
{ |
||||
if ((!d_current_algorithm && (algid == crypto_algorithm::NONE)) || // This line should be commented out if 'null_algorithm' is to be tested
|
||||
(d_current_algorithm && (algid == d_current_algorithm->id()))) |
||||
return d_current_algorithm; |
||||
|
||||
switch (algid) |
||||
{ |
||||
case crypto_algorithm::DES_OFB: |
||||
d_current_algorithm = crypto_algorithm::sptr(new des_ofb()); |
||||
break; |
||||
//case crypto_algorithm::NONE:
|
||||
// d_current_algorithm = crypto_algorithm::sptr(new null_algorithm());
|
||||
// break;
|
||||
default: |
||||
d_current_algorithm = crypto_algorithm::sptr(); |
||||
}; |
||||
|
||||
if (d_current_algorithm) |
||||
{ |
||||
d_current_algorithm->set_logging(logging_enabled()); |
||||
|
||||
if (!d_persistent_key_map.empty()) |
||||
d_current_algorithm->set_key_map(d_persistent_key_map); |
||||
|
||||
if (!d_persistent_key.empty()) |
||||
d_current_algorithm->set_key(d_persistent_key); |
||||
} |
||||
|
||||
return d_current_algorithm; |
||||
} |
||||
|
||||
void crypto_module::set_key(const crypto_algorithm::key_type& key) |
||||
{ |
||||
d_persistent_key = key; |
||||
|
||||
if (d_current_algorithm) |
||||
d_current_algorithm->set_key(d_persistent_key); |
||||
} |
||||
|
||||
void crypto_module::set_key_map(const crypto_algorithm::key_map_type& keys) |
||||
{ |
||||
d_persistent_key_map = keys; |
||||
|
||||
if (d_current_algorithm) |
||||
d_current_algorithm->set_key_map(d_persistent_key_map); |
||||
} |
||||
|
||||
void crypto_module::set_logging(bool on/* = true*/) |
||||
{ |
||||
d_verbose = on; |
||||
|
||||
if (d_current_algorithm) |
||||
d_current_algorithm->set_logging(on); |
||||
} |
@ -0,0 +1,73 @@ |
||||
#ifndef INCLUDED_CRYPTO_H |
||||
#define INCLUDED_CRYPTO_H |
||||
|
||||
#include <stdint.h> |
||||
#include <vector> |
||||
#include <map> |
||||
#include <boost/shared_ptr.hpp> |
||||
|
||||
static const int MESSAGE_INDICATOR_LENGTH = 9; |
||||
|
||||
class CryptoState |
||||
{ |
||||
public: |
||||
CryptoState() : |
||||
kid(0), algid(0), mi(MESSAGE_INDICATOR_LENGTH) |
||||
{ } |
||||
public: |
||||
std::vector<uint8_t> mi; |
||||
uint16_t kid; |
||||
uint8_t algid; |
||||
}; |
||||
|
||||
class crypto_state_provider |
||||
{ |
||||
public: |
||||
virtual struct CryptoState crypto_state() const=0; |
||||
}; |
||||
|
||||
class crypto_algorithm |
||||
{ |
||||
public: |
||||
typedef boost::shared_ptr<class crypto_algorithm> sptr; |
||||
typedef std::vector<uint8_t> key_type; |
||||
typedef std::map<uint16_t, key_type > key_map_type; |
||||
typedef uint8_t type_id; |
||||
enum |
||||
{ |
||||
NONE = 0x80, |
||||
DES_OFB = 0x81, |
||||
}; |
||||
public: |
||||
virtual const type_id id() const=0; |
||||
virtual bool set_key(const key_type& key)=0; |
||||
virtual void set_key_map(const key_map_type& key_map)=0; |
||||
virtual bool update(const struct CryptoState& state)=0; |
||||
virtual uint64_t generate(size_t n_bits)=0; // Can request up to 64 bits of key stream at one time
|
||||
virtual void set_logging(bool on)=0; |
||||
}; |
||||
|
||||
class crypto_module |
||||
{ |
||||
public: |
||||
typedef boost::shared_ptr<class crypto_module> sptr; |
||||
public: |
||||
crypto_module(bool verbose = false); |
||||
public: |
||||
virtual crypto_algorithm::sptr algorithm(crypto_algorithm::type_id algid); |
||||
virtual void set_key(const crypto_algorithm::key_type& key); |
||||
virtual void set_key_map(const crypto_algorithm::key_map_type& keys); |
||||
virtual void set_logging(bool on = true); |
||||
protected: |
||||
crypto_algorithm::sptr d_current_algorithm; |
||||
crypto_algorithm::key_type d_persistent_key; |
||||
crypto_algorithm::key_map_type d_persistent_key_map; |
||||
bool d_verbose; |
||||
public: |
||||
virtual crypto_algorithm::sptr current_algorithm() const |
||||
{ return d_current_algorithm; } |
||||
virtual bool logging_enabled() const |
||||
{ return d_verbose; } |
||||
}; |
||||
|
||||
#endif // INCLUDED_CRYPTO_H
|
@ -0,0 +1,64 @@ |
||||
#include "crypto_module_du_handler.h" |
||||
|
||||
#include "abstract_data_unit.h" |
||||
|
||||
#include <boost/format.hpp> |
||||
#include <sstream> |
||||
#include <stdio.h> |
||||
|
||||
crypto_module_du_handler::crypto_module_du_handler(data_unit_handler_sptr next, crypto_module::sptr crypto_mod) |
||||
: data_unit_handler(next) |
||||
, d_crypto_mod(crypto_mod) |
||||
{ |
||||
} |
||||
|
||||
void |
||||
crypto_module_du_handler::handle(data_unit_sptr du) |
||||
{ |
||||
if (!d_crypto_mod) |
||||
{ |
||||
data_unit_handler::handle(du); |
||||
return; |
||||
} |
||||
|
||||
crypto_state_provider* p = dynamic_cast<crypto_state_provider*>(du.get()); |
||||
if (p == NULL) |
||||
{ |
||||
data_unit_handler::handle(du); |
||||
return; |
||||
} |
||||
|
||||
CryptoState state = p->crypto_state(); |
||||
|
||||
///////////////////////////////////
|
||||
|
||||
if (d_crypto_mod->logging_enabled()) |
||||
{ |
||||
std::string duid_str("?"); |
||||
abstract_data_unit* adu = dynamic_cast<abstract_data_unit*>(du.get()); |
||||
if (adu) |
||||
duid_str = adu->duid_str(); |
||||
|
||||
std::stringstream ss; |
||||
for (size_t n = 0; n < state.mi.size(); ++n) |
||||
ss << (boost::format("%02x") % (int)state.mi[n]); |
||||
|
||||
fprintf(stderr, "%s:\tAlgID: 0x%02x, KID: 0x%04x, MI: %s\n", duid_str.c_str(), state.algid, state.kid, ss.str().c_str()); |
||||
} |
||||
|
||||
///////////////////////////////////
|
||||
|
||||
crypto_algorithm::sptr algorithm = d_crypto_mod->algorithm(state.algid); |
||||
if (!algorithm) |
||||
{ |
||||
data_unit_handler::handle(du); |
||||
return; |
||||
} |
||||
|
||||
// TODO: Could do key management & selection here with 'state.kid'
|
||||
// Assuming we're only using one key (ignoring 'kid')
|
||||
|
||||
algorithm->update(state); |
||||
|
||||
data_unit_handler::handle(du); |
||||
} |
@ -0,0 +1,21 @@ |
||||
#ifndef INCLUDED_CRYPTO_MODULE_DU_HANDLER_H |
||||
#define INCLUDED_CRYPTO_MODULE_DU_HANDLER_H |
||||
|
||||
#include <boost/shared_ptr.hpp> |
||||
|
||||
#include "data_unit_handler.h" |
||||
#include "crypto.h" |
||||
|
||||
class crypto_module_du_handler : public data_unit_handler |
||||
{ |
||||
public: |
||||
crypto_module_du_handler(data_unit_handler_sptr next, crypto_module::sptr crypto_mod); |
||||
public: |
||||
typedef boost::shared_ptr<class crypto_module_du_handler> sptr; |
||||
public: |
||||
virtual void handle(data_unit_sptr du); |
||||
private: |
||||
crypto_module::sptr d_crypto_mod; |
||||
}; |
||||
|
||||
#endif //INCLUDED_CRYPTO_MODULE_HANDLER_H
|
@ -0,0 +1,15 @@ |
||||
typedef unsigned long DES_KS[16][2]; /* Single-key DES key schedule */ |
||||
typedef unsigned long DES3_KS[48][2]; /* Triple-DES key schedule */ |
||||
|
||||
/* In deskey.c: */ |
||||
void deskey(DES_KS,unsigned char *,int); |
||||
void des3key(DES3_KS,unsigned char *,int); |
||||
|
||||
/* In desport.c, desborl.cas or desgnu.s: */ |
||||
void des(DES_KS,unsigned char *); |
||||
/* In des3port.c, des3borl.cas or des3gnu.s: */ |
||||
void des3(DES3_KS,unsigned char *); |
||||
|
||||
extern int Asmversion; /* 1 if we're linked with an asm version, 0 if C */ |
||||
|
||||
|
@ -0,0 +1,124 @@ |
||||
/* Portable C code to create DES key schedules from user-provided keys
|
||||
* This doesn't have to be fast unless you're cracking keys or UNIX |
||||
* passwords |
||||
*/ |
||||
|
||||
#include <string.h> |
||||
#include "des.h" |
||||
|
||||
/* Key schedule-related tables from FIPS-46 */ |
||||
|
||||
/* permuted choice table (key) */ |
||||
static unsigned char pc1[] = { |
||||
57, 49, 41, 33, 25, 17, 9, |
||||
1, 58, 50, 42, 34, 26, 18, |
||||
10, 2, 59, 51, 43, 35, 27, |
||||
19, 11, 3, 60, 52, 44, 36, |
||||
|
||||
63, 55, 47, 39, 31, 23, 15, |
||||
7, 62, 54, 46, 38, 30, 22, |
||||
14, 6, 61, 53, |