cipher for sha1/sha256/sha224/sha512/sha384 md5 hmac aes 3des pbkdf2 rsa digest.

This commit is contained in:
unknown 2015-09-18 18:52:34 +08:00
parent baaef1e534
commit 061d2cf317
67 changed files with 15454 additions and 0 deletions

15
Makefile.comm Normal file
View File

@ -0,0 +1,15 @@
#CFLAGS = -DDEBUG_LOG -D_DEBUG
#CFLAGS = -DDEBUG_LOG
CFLAGS = -DLINUX
CC=gcc -std=c++11 -g -O3 $(CFLAGS)
CC=gcc -std=c++11 -g $(CFLAGS)
CCC=gcc -std=c++11 -g $(CFLAGS)
SHARED_FLAG = -fPIC -shared
%.o : %.cpp
$(CC) $(INC) -c $< -o $@
%.o : %.c
$(CC) $(INC) -c $< -o $@
%.o : %.cc
$(CC) $(INC) -c $< -o $@

252
base/base64.cpp Normal file
View File

@ -0,0 +1,252 @@
/*
** Copyright (C) 2014 Wang Yaofu
** All rights reserved.
**
**Author:Wang Yaofu voipman@qq.com
**Description: The source file of base64.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "base64.h"
namespace {
static const unsigned char EncodeTable[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const unsigned char* DecodeTable = NULL;
void FillDecodeTable() {
// double buffer is used here for thread safe.
static unsigned char DecodeTableBuff[256];
unsigned char buff[256];
if (DecodeTable != NULL) {
return;
}
::memset(buff, 0x80, sizeof(buff));
for (size_t k = 0; k < sizeof(EncodeTable); ++k) {
buff[(size_t)EncodeTable[k]] = k;
}
// to mark those valid characters in encoded string, but not in these
// 64 bases list.
buff[(size_t)'\r'] = buff[(size_t)'\n'] = 0x4F;
buff[(size_t)'='] = 0x40;
::memcpy(DecodeTableBuff, buff, sizeof(DecodeTableBuff));
DecodeTable = DecodeTableBuff;
}
// Get the next 4 characters from input string, '\r\n' will be trimmed off.
// The input string starts from 'p', and ends before 'q'. 'buff' is for
// storing the return characters.
// The return value, -1: error, there aren't 4 characters available, or get
// invalid character. 0-4 mean the number of valid characters, '=' is excluded.
int GetNext4EncodedCharacters(const unsigned char*& p,
const unsigned char* q,
unsigned char* buff) {
int k = 0;
unsigned char c = 0;
while (k < 4 && p < q) {
c = DecodeTable[*p];
if ((c & 0xC0) == 0) { // normal valid characters
*buff++ = c;
++p;
++k;
} else if (c & 0x80) { // not ('\r' or '\n' or '=')
return -1;
} else if (*p == '=') {
break;
} else { // ('\r' or '\n')
++p;
}
}
// success. this should be most of the cases, return as soon as possible
if (k == 4) {
return 4;
}
// get a '='
if (p < q && *p == '=') {
++p;
// there should be 4 characters in the last encode group
int tail = 4 - k - 1;
// there should not be more than 2 '=' in the end
if (tail > 1) {
return -1;
}
while (tail > 0 && p < q && ((DecodeTable[*p] & 0x40) == 0x40)) {
if (*p == '=') {
--tail;
}
++p;
}
// any character not ('\r' or '\n' or '=') appears after '='
if (tail != 0) {
return -1;
}
// only ('\r' || '\n') is allowed at the end
while (p < q) {
if ((DecodeTable[*p] & 0x4F) == 0x4F) {
++p;
} else {
return -1;
}
}
return k;
}
// for ('\r' or '\n') at very end
while (p < q && (DecodeTable[*p] & 0x4F) == 0x4F) {
++p;
}
if (k == 0 && p == q) {
return 0;
}
return -1;
}
size_t ExpectedEncodeLength(size_t len)
{
size_t encodedLen = ((len * 4 / 3 + 3) / 4) * 4;
return encodedLen;
}
size_t ExpectedDecodeLength(size_t len)
{
return (size_t)((len + 3) / 4 * 3);
}
} // anonymous namespace
bool Base64Encode(const std::string& input, std::string* output)
{
assert(output);
output->resize(ExpectedEncodeLength(input.size()));
char* buff = const_cast<char*>(output->data());
size_t len = output->size();
if (!Base64Encode(input, buff, &len)) {
output->clear();
return false;
}
output->resize(len);
return true;
}
bool Base64Encode(const std::string& input, char* output, size_t* len)
{
assert(output);
char* buff = output;
if (__builtin_expect(*len < ExpectedEncodeLength(input.size()), 0)) {
return false;
}
unsigned char *p = (unsigned char*)input.data();
unsigned char *q = p + input.size();
unsigned char c1, c2, c3;
// process 3 char every loop
for (; p + 3 <= q; p += 3) {
c1 = *p;
c2 = *(p + 1);
c3 = *(p + 2);
*buff++ = EncodeTable[c1 >> 2];
*buff++ = EncodeTable[((c1 << 4) | (c2 >> 4)) & 0x3f];
*buff++ = EncodeTable[((c2 << 2) | (c3 >> 6)) & 0x3f];
*buff++ = EncodeTable[c3 & 0x3f];
}
// the reminders
if (q - p == 1) {
c1 = *p;
*buff++ = EncodeTable[(c1 & 0xfc) >> 2];
*buff++ = EncodeTable[(c1 & 0x03) << 4];
*buff++ = '=';
*buff++ = '=';
} else if (q - p == 2) {
c1 = *p;
c2 = *(p + 1);
*buff++ = EncodeTable[(c1 & 0xfc) >> 2];
*buff++ = EncodeTable[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
*buff++ = EncodeTable[((c2 & 0x0f) << 2)];
*buff++ = '=';
}
*len = buff - output;
return true;
}
bool Base64Decode(const std::string& input, std::string* output)
{
assert(output);
output->resize(ExpectedDecodeLength(input.size()));
char* buff = const_cast<char*>(output->data());
size_t len = output->size();
if (!Base64Decode(input, buff, &len)) {
output->clear();
return false;
}
output->resize(len);
return true;
}
bool Base64Decode(const std::string& input, char* output, size_t* len)
{
assert(output && len);
char* buff = output;
if (__builtin_expect(*len < ExpectedDecodeLength(input.size()), 0)) {
return false;
}
if (__builtin_expect(!DecodeTable, 0)) {
FillDecodeTable();
}
if (input.empty()) {
*len = buff - output;
return true;
}
const unsigned char* p = (unsigned char*)input.data();
const unsigned char* q = (unsigned char*)input.data() + input.size();
// handle 4 bytes in every loop
while (true) {
char ch = 0;
unsigned char encoded[4];
int len = GetNext4EncodedCharacters(p, q, encoded);
if (__builtin_expect(len == 4, 1)) {
ch = encoded[0] << 2; // all 6 bits
ch |= encoded[1] >> 4; // 2 high bits
*buff++ = ch;
ch = encoded[1] << 4; // 4 low bits
ch |= encoded[2] >> 2; // 4 high bits
*buff++ = ch;
ch = encoded[2] << 6; // 2 low bits
ch |= encoded[3];
*buff++ = ch;
} else if (len >= 2) {
ch = encoded[0] << 2; // all 6 bits
ch |= encoded[1] >> 4; // 2 high bits
*buff++ = ch;
if (len == 3) {
ch = encoded[1] << 4; // 4 low bits
ch |= encoded[2] >> 2; // 4 high bits
*buff++ = ch;
}
} else if (len == 0) {
break;
} else {
return false;
}
}
*len = buff - output;
return true;
}

17
base/base64.h Normal file
View File

@ -0,0 +1,17 @@
/*
** Copyright (C) 2014 Wang Yaofu
** All rights reserved.
**
**Author:Wang Yaofu voipman@qq.com
**Description: The header file of base64.
*/
#ifndef _BASE64UTILS_H_
#define _BASE64UTILS_H_
#include <string>
bool Base64Encode(const std::string& input, std::string* output);
bool Base64Encode(const std::string& input, char* output, size_t* len);
bool Base64Decode(const std::string& input, std::string* output);
bool Base64Decode(const std::string& input, char* output, size_t* len);
#endif // #define _BASE64UTILS_H_

337
base/stringutils.cpp Normal file
View File

@ -0,0 +1,337 @@
/*
** Copyright (C) 2014 Wang Yaofu
** All rights reserved.
**
**Author:Wang Yaofu voipman@qq.com
**Description: The source file of class CStringUitls.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdarg>
#include <iomanip>
#include "stringutils.h"
namespace common {
const char kWhitespaceASCII[] =
{
0x09, // <control-0009> to <control-000D>
0x0A,
0x0B,
0x0C,
0x0D,
0x20, // Space
0
};
template<typename STR>
void TrimStringT(const STR& input,
const typename STR::value_type trim_chars[],
TrimOption option,
STR* output) {
// Find the edges of leading/trailing whitespace as desired.
const typename STR::size_type last_char = input.length() - 1;
const typename STR::size_type first_good_char = (option & kTrimLeading) ?
input.find_first_not_of(trim_chars) : 0;
const typename STR::size_type last_good_char = (option & kTrimTrailing) ?
input.find_last_not_of(trim_chars) : last_char;
// When the string was all whitespace, report that we stripped off
// whitespace from whichever position the caller was interested in.
// For empty input, we stripped no whitespace, but we still need to
// clear |output|.
if (input.empty() ||
(first_good_char == STR::npos) || (last_good_char == STR::npos)) {
output->clear();
return;
}
// Trim the whitespace.
*output =
input.substr(first_good_char, last_good_char - first_good_char + 1);
}
void StrUtils::TrimWhitespace(const std::string& input,
TrimOption option,
std::string* output) {
TrimStringT(input, kWhitespaceASCII, option, output);
}
void StrUtils::ReplaceString(const std::string& input,
const std::string& old_val,
const std::string& new_val,
std::string* output) {
if (old_val.empty()) {
return;
}
std::ostringstream ss;
std::string::size_type pos = 0;
std::string::size_type pos_prev = 0;
while (pos != std::string::npos) {
pos_prev = pos;
if ((pos = input.find(old_val, pos)) != std::string::npos) {
if (pos > pos_prev) {
ss << input.substr(pos_prev, pos - pos_prev);
}
ss << new_val;
pos += old_val.length();
} else {
if (pos_prev + 1 <= input.length()) {
ss << input.substr(pos_prev);
}
break;
}
}
*output = ss.str();
}
std::string StrUtils::ToLowerCase(const std::string& input) {
if (input.empty()) {
return std::string();
}
std::string output(input);
std::string::pointer begin = &output[0];
std::string::pointer end = begin + output.size();
for (; begin < end; ++begin) {
*begin = tolower(*begin);
}
return output;
}
std::string StrUtils::ToUpperCase(const std::string& input) {
if (input.empty()) {
return std::string();
}
std::string output(input);
std::string::pointer begin = &output[0];
std::string::pointer end = begin + output.size();
for (; begin < end; ++begin) {
*begin = toupper(*begin);
}
return output;
}
template <typename STR>
void SplitStringT(const STR& str,
const STR& s,
std::vector<STR>* r) {
r->clear();
typename STR::size_type begin_index = 0;
while (true) {
const typename STR::size_type end_index = str.find(s, begin_index);
if (end_index == STR::npos) {
const STR term = str.substr(begin_index);
r->push_back(term);
return;
}
const STR term = str.substr(begin_index, end_index - begin_index);
r->push_back(term);
begin_index = end_index + s.size();
}
}
void StrUtils::SplitString(const std::string& str,
const std::string& s,
std::vector<std::string>* r) {
SplitStringT(str, s, r);
}
bool StrUtils::Split(const std::string& s,
char sep,
std::string& first,
std::string& second) {
std::string::size_type sep_pos = s.find(sep);
first = s.substr(0, sep_pos);
if (sep_pos!=std::string::npos)
second = s.substr(sep_pos+1);
return true;
}
int StrUtils::stoi(const std::string &str) {
return ::atoi(str.c_str());
}
long StrUtils::stol(const std::string &str, const int base) {
char *ep;
return ::strtol(str.c_str(), &ep, base);
}
long long StrUtils::stoll(const std::string &str, const int base) {
char *ep;
return ::strtoll(str.c_str(), &ep, base);
}
unsigned long StrUtils::stoul(const std::string &str, const int base) {
char *ep;
return ::strtoul(str.c_str(), &ep, base);
}
unsigned long long StrUtils::stoull(const std::string &str, const int base) {
char *ep;
return ::strtoull(str.c_str(), &ep, base);
}
float StrUtils::stof(const std::string& str) {
char *ep;
return ::strtof(str.data(), &ep);
}
double StrUtils::stod(const std::string& str) {
char *ep;
return ::strtold(str.data(), &ep);
}
long double StrUtils::stold(const std::string& str) {
char *ep;
return ::strtod(str.data(), &ep);
}
std::string StrUtils::JoinStr(std::vector<std::string>& parts,
const std::string& delimiter) {
if (parts.empty()) {
return "";
}
std::stringstream ss;
for (size_t i = 0; i < parts.size() - 1; ++i) {
ss << parts[i];
ss << delimiter;
}
ss << parts[parts.size() - 1]; //no delimiter at last
return ss.str();
}
std::string StrUtils::JoinStr(std::vector<std::string>& parts, char delimiter) {
std::string tmp;
tmp.assign(1, delimiter);
return JoinStr(parts, tmp);
}
std::string StrUtils::Hex(const char* cpSrcStr, int len, bool isUpper) {
if (cpSrcStr == NULL) {
return "";
}
std::string ret(len * 2, 0x00);
const char* hex = isUpper ? "0123456789ABCDEF" : "0123456789abcdef";
for (size_t i = 0; i < len; ++i) {
unsigned char v = static_cast<unsigned char>(cpSrcStr[i]);
ret[2*i] = hex[(v >> 4) & 0x0f];
ret[2*i+1] = hex[ v & 0x0f];
}
return ret;
}
std::string StrUtils::Hex(const std::string& srcStr, bool isUpper) {
return Hex(srcStr.c_str(), srcStr.size(), isUpper);
}
std::string StrUtils::Hex(const char ch, bool isUpper) {
return Hex(&ch, 1, isUpper);
}
namespace {
char asc_bcd(const char *what) {
unsigned char digit;
unsigned char m;
digit = (what[0] >= 'a' ? ((what[0]) - 'a') + 10 : (what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'a' ? ((what[1]) - 'a') + 10 : (what[1] - '0'));
return(digit);
}
}
std::string StrUtils::fromHex(const char* from, size_t len) {
std::string ret(len / 2, 0x00);
for (size_t ii = 0; ii < len / 2; ii++)
ret[ii] = asc_bcd(from + ii * 2);
return ret;
}
std::string StrUtils::fromHex(const std::string& from) {
return fromHex(from.c_str(), from.length());
}
int StrUtils::fromHex(const char* from, char* to) {
int len = strlen(from)/2;
for (size_t ii = 0; ii < len; ii++)
to[ii] = asc_bcd(from + ii * 2);
return len;
}
int StrUtils::HexStr2Int(const char* aStr, int len) {
int i, res = 0;
for(i = 0; i < len; i++) {
res *= 16;
if ((aStr[i] >= '0') && (aStr[i] <= '9')) {
res += aStr[i] - '0';
} else if ((aStr[i] >= 'a') && (aStr[i] <= 'f')) {
res += aStr[i] - 'a' + 10;
} else if ((aStr[i] >= 'A') && (aStr[i] <= 'F')) {
res += aStr[i] - 'A' + 10;
} else {
return 0;
}
}
return res;
}
int StrUtils::HexStr2Int(const std::string& srcStr) {
return HexStr2Int(srcStr.c_str(), srcStr.length());
}
int StrUtils::Int2HexInt(int src) {
std::string hexStr;
Format(hexStr, "%d", src);
return HexStr2Int(hexStr.c_str(), hexStr.length());
}
bool StrUtils::IsNumber(char ch) {
return (ch >= '0' && ch <= '9');
}
bool StrUtils::IsLetter(char ch) {
return ((ch >= 'a' && ch <= 'z') || ((ch >= 'A') && (ch <= 'Z')));
}
bool StrUtils::IsUnderLine(char ch) {
return (ch == '_');
}
bool StrUtils::Format(std::string &outStr, const char *format, ...) {
char* mem;
va_list ap;
va_start(ap, format);
if (vasprintf(&mem, format, ap) < 0) {
va_end(ap);
return false;
}
outStr = mem;
va_end(ap);
free(mem);
return true;
}
unsigned int StrUtils::ELFhash(const char* aStr, unsigned int aHashMod) {
unsigned int h = 0;
while (*aStr) {
h = (h << 4) + *aStr++;
unsigned int g = h & 0xF0000000;
if (g) h ^= g >> 24;
h &= ~g;
}
return h % aHashMod;
}
unsigned int StrUtils::HfIp(const char* aStr, unsigned int aHashMod) {
unsigned int n = 0;
unsigned char* b = (unsigned char*)&n;
for (unsigned int i = 0; aStr[i] != 0x00; i++)
b[i%4] ^= aStr[i];
return n % aHashMod;
}
unsigned int StrUtils::hf(const char* aStr, unsigned int aHashMod) {
int result = 0;
const char* ptr = aStr;
int c;
for (int i = 1; (c = *ptr++); i++)
result += c * 3 * i;
if (result < 0) result = -result;
return result % aHashMod;
}
}// namespace common

166
base/stringutils.h Normal file
View File

@ -0,0 +1,166 @@
/*
** Copyright (C) 2014 Wang Yaofu
** All rights reserved.
**
**Author:Wang Yaofu voipman@qq.com
**Description: The header file of class CStringUitls.
*/
#pragma once
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <cctype>
namespace common {
enum TrimOption {
kTrimNone = 0,
kTrimLeading = 1 << 0,
kTrimTrailing = 1 << 1,
kTrimAll = kTrimLeading | kTrimTrailing,
};
class StrUtils {
public:
static void TrimWhitespace(const std::string& input,
TrimOption option, std::string* output);
static void ReplaceString(const std::string& input,
const std::string& old_val,
const std::string& new_val,
std::string* output);
static std::string ReplaceString(const std::string& input,
const std::string& old_val,
const std::string& new_val) {
std::string output;
ReplaceString(input, old_val, new_val, &output);
return output;
}
static void Trim(std::string& aStr, const std::string& aSep,
TrimOption aOption = kTrimTrailing) {
size_t pos = 0;
if (aOption & kTrimLeading) {
pos = aStr.find(aSep);
if (pos != aStr.npos) {
aStr.erase(0, pos + 1);
}
}
if (aOption & kTrimTrailing) {
pos = aStr.rfind(aSep);
if (pos != aStr.npos) {
aStr.erase(pos);
}
}
}
// ABC => abc
static std::string ToLowerCase(const std::string& input);
// str => STR
static std::string ToUpperCase(const std::string& input);
// 11&22&33 +& =>11 22 33 + &
static void SplitString(const std::string& str,
const std::string& s,
std::vector<std::string>* r);
// string to split string
static bool Split(const std::string& s,
char sep,
std::string& first,
std::string& second);
// any to string.
template <typename INT_TYPE>
static std::string to_string(const INT_TYPE& aValue) {
std::stringstream ss;
ss << aValue;
return ss.str();
}
template <typename K, typename V>
static std::string to_string(const typename std::pair<K, V>& v) {
std::ostringstream o;
o << to_string(v.first) << ": " << to_string(v.second);
return o.str();
}
template <typename T>
static std::string to_string(const T& beg, const T& end) {
std::ostringstream o;
for (T it = beg; it != end; ++it) {
if (it != beg)
o << ", ";
o << to_string(*it);
}
return o.str();
}
template <typename T>
static std::string to_string(const std::vector<T>& t) {
std::ostringstream o;
o << "[" << to_string(t.begin(), t.end()) << "]";
return o.str();
}
template <typename T>
static std::string to_string(const std::list<T>& t) {
std::ostringstream o;
o << "[" << to_string(t.begin(), t.end()) << "]";
return o.str();
}
template <typename K, typename V>
static std::string to_string(const std::map<K, V>& m) {
std::ostringstream o;
o << "{" << to_string(m.begin(), m.end()) << "}";
return o.str();
}
template <typename T>
static std::string to_string(const std::set<T>& s) {
std::ostringstream o;
o << "{" << to_string(s.begin(), s.end()) << "}";
return o.str();
}
template <class Type>
static Type stringToNum(const std::string& str) {
std::istringstream iss(str);
Type num;
iss >> num;
return num;
}
static int stoi(const std::string &str);
static long stol(const std::string &str, const int base = 10);
static long long stoll(const std::string &str, const int base = 10);
static unsigned long stoul(const std::string &str, const int base = 10);
static unsigned long long stoull(const std::string &str, const int base = 10);
static float stof(const std::string& str);
static double stod(const std::string& str);
static long double stold(const std::string& str);
// 11 22 33 + & => 11&22&33
static std::string JoinStr(std::vector<std::string>& parts, char delimiter);
// 11 22 33 + %% => 11%%22%%33
static std::string JoinStr(std::vector<std::string>& parts, const std::string& delimiter);
// 19AaZz\n => 31 39 41 61 5a 7a 0a
static std::string Hex(const char* cpSrcStr, int len, bool isUpper = false);
static std::string Hex(const std::string& srcStr, bool isUpper = false);
static std::string Hex(const char ch, bool isUpper = false);
static std::string fromHex(const char* from, size_t len);
static int fromHex(const char* from, char* to);
static std::string fromHex(const std::string& from);
static int HexStr2Int(const char* aStr, int len);
static int HexStr2Int(const std::string& srcStr);
static int Int2HexInt(int src);
static bool IsNumber(char ch);
static bool IsLetter(char ch);
static bool IsUnderLine(char ch);
static bool Format(std::string &outStr, const char *format, ...);
static unsigned int HfIp(const char* aStr, unsigned int aHashMod);
static unsigned int hf(const char* aStr, unsigned int aHashMod);
// System - v hash method, it is nice.
static unsigned int ELFhash(const char* aStr, unsigned int aHashMod = 0x7FFFFFFF);
};
} // namespace common

26
cipher/Makefile Normal file
View File

@ -0,0 +1,26 @@
include ../Makefile.comm
INC += -I../
INC += -I./
SOURCES = $(foreach d,.,$(wildcard $(d)/*.c))
OBJS = $(patsubst %.c, %.o, $(SOURCES))
OBJS += md5key.o
CC += $(SHARED_FLAG)
all : libcipher.a
libcipher.a : $(OBJS)
ar -rus $@ $^
echo $(OBJS)
echo $(SOURCES)
@echo ""
@echo "+--------------------------------------------+"
@echo "| Finish compilation |"
@echo "+--------------------------------------------+"
@echo "| Thanks using libcipher.a |"
@echo "| copyright(c)Wang Yaofu voipman@qq.com |"
@echo "+--------------------------------------------+"
clean:
rm -rf *.o *.a

1246
cipher/aes.c Normal file

File diff suppressed because it is too large Load Diff

13
cipher/aes.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _CIPHER_AES_H
#define _CIPHER_AES_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_AES_H */

108
cipher/digest.c Normal file
View File

@ -0,0 +1,108 @@
#include <string.h>
#include "md5.h"
#include "digest.h"
void CvtHex(
IN HASH Bin,
OUT HASHHEX Hex
)
{
unsigned short i;
unsigned char j;
for (i = 0; i < HASHLEN; i++) {
j = (Bin[i] >> 4) & 0xf;
if (j <= 9)
Hex[i*2] = (j + '0');
else
Hex[i*2] = (j + 'a' - 10);
j = Bin[i] & 0xf;
if (j <= 9)
Hex[i*2+1] = (j + '0');
else
Hex[i*2+1] = (j + 'a' - 10);
};
Hex[HASHHEXLEN] = '\0';
};
/* calculate H(A1) as per spec */
void DigestCalcHA1(
IN unsigned char * pszAlg,
IN unsigned char * pszUserName,
IN unsigned char * pszRealm,
IN unsigned char * pszPassword,
IN unsigned char * pszNonce,
IN unsigned char * pszCNonce,
OUT HASHHEX SessionKey
)
{
MD5_CTX Md5Ctx;
HASH HA1;
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));
MD5Final(HA1, &Md5Ctx);
if (memcmp(pszAlg, "md5-sess", 8) == 0) {
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, HA1, HASHLEN);
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
MD5Final(HA1, &Md5Ctx);
};
CvtHex(HA1, SessionKey);
};
/* calculate request-digest/response-digest as per HTTP Digest spec */
void DigestCalcResponse(
IN HASHHEX HA1, /* H(A1) */
IN unsigned char * pszNonce, /* nonce from server */
IN unsigned char * pszNonceCount, /* 8 hex digits */
IN unsigned char * pszCNonce, /* client nonce */
IN unsigned char * pszQop, /* qop-value: "", "auth", "auth-int" */
IN unsigned char * pszMethod, /* method from the request */
IN unsigned char * pszDigestUri, /* requested URL */
IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
OUT HASHHEX Response /* request-digest or response-digest */
)
{
MD5_CTX Md5Ctx;
HASH HA2;
HASH RespHash;
HASHHEX HA2Hex;
// calculate H(A2)
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
if (memcmp(pszQop, "auth-int", 8) == 0) {
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
};
MD5Final(HA2, &Md5Ctx);
CvtHex(HA2, HA2Hex);
// calculate response
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
MD5Update(&Md5Ctx, ":", 1);
if (*pszQop) {
MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszQop, strlen(pszQop));
MD5Update(&Md5Ctx, ":", 1);
};
MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
MD5Final(RespHash, &Md5Ctx);
CvtHex(RespHash, Response);
};

43
cipher/digest.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef _CIPHER_DIGEST_H_
#define _CIPHER_DIGEST_H_
/* from rfc2617 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define HASHLEN 16
typedef unsigned char HASH[HASHLEN];
#define HASHHEXLEN 32
typedef unsigned char HASHHEX[HASHHEXLEN+1];
#define IN
#define OUT
/* calculate H(A1) as per HTTP Digest spec */
void DigestCalcHA1(
IN unsigned char * pszAlg,
IN unsigned char * pszUserName,
IN unsigned char * pszRealm,
IN unsigned char * pszPassword,
IN unsigned char * pszNonce,
IN unsigned char * pszCNonce,
OUT HASHHEX SessionKey
);
/* calculate request-digest/response-digest as per HTTP Digest spec */
void DigestCalcResponse(
IN HASHHEX HA1, /* H(A1) */
IN unsigned char * pszNonce, /* nonce from server */
IN unsigned char * pszNonceCount, /* 8 hex digits */
IN unsigned char * pszCNonce, /* client nonce */
IN unsigned char * pszQop, /* qop-value: "", "auth", "auth-int" */
IN unsigned char * pszMethod, /* method from the request */
IN unsigned char * pszDigestUri, /* requested URL */
IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
OUT HASHHEX Response /* request-digest or response-digest */
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_DIGEST_H_ */

219
cipher/hmac.c Normal file
View File

@ -0,0 +1,219 @@
#include <string.h>
#include "hmac.h"
#include "md5.h"
#include "sha.h"
#include "sha224.h"
#include "sha256.h"
#include "sha384.h"
#include "sha512.h"
/*
unsigned char* text; pointer to data stream
int text_len; length of data stream
unsigned char* key; pointer to authentication key
int key_len; length of authentication key
unsigned char* digest; caller digest to be filled in
*/
#define KEY_IOPAD_SIZE 64
void hmac_md5(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac)
{
MD5_CTX context;
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
int i;
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in pads */
memset( k_ipad, 0, sizeof(k_ipad));
memset( k_opad, 0, sizeof(k_opad));
memcpy( k_ipad, key, key_len);
memcpy( k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner MD5
MD5Init(&context); /* init context for 1st pass */
MD5Update(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
MD5Update(&context, (unsigned char*)text, text_len); /* then text of datagram */
MD5Final(hmac, &context); /* finish up 1st pass */
// perform outer MD5
MD5Init(&context); /* init context for 2nd pass */
MD5Update(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
MD5Update(&context, hmac, MD5_DIGEST_SIZE); /* then results of 1st hash */
MD5Final(hmac, &context); /* finish up 2nd pass */
}
void hmac_sha1(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac) {
SHA_State context;
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
int i;
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA
SHA_Init(&context); /* init context for 1st pass */
SHA_Bytes(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
SHA_Bytes(&context, text, text_len); /* then text of datagram */
SHA_Final(&context, hmac); /* finish up 1st pass */
// perform outer SHA
SHA_Init(&context); /* init context for 2nd pass */
SHA_Bytes(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
SHA_Bytes(&context, hmac, SHA1_DIGEST_SIZE); /* then results of 1st hash */
SHA_Final(&context, hmac); /* finish up 2nd pass */
}
void hmac_sha224(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac) {
SHA256_State context;
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
int i;
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA224
SHA224_Init(&context); /* init context for 1st pass */
SHA224_Bytes(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
SHA224_Bytes(&context, (unsigned char*)text, text_len); /* then text of datagram */
SHA224_Final(&context, hmac); /* finish up 1st pass */
// perform outer SHA224
SHA224_Init(&context); /* init context for 2nd pass */
SHA224_Bytes(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
SHA224_Bytes(&context, hmac, SHA224_DIGEST_SIZE); /* then results of 1st hash */
SHA224_Final(&context, hmac); /* finish up 2nd pass */
}
void hmac_sha256(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac) {
SHA256_State context;
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
int i;
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA256
SHA256_Init(&context); /* init context for 1st pass */
SHA256_Bytes(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
SHA256_Bytes(&context, text, text_len); /* then text of datagram */
SHA256_Final(&context, hmac); /* finish up 1st pass */
// perform outer SHA256
SHA256_Init(&context); /* init context for 2nd pass */
SHA256_Bytes(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
SHA256_Bytes(&context, hmac, SHA256_DIGEST_SIZE); /* then results of 1st hash */
SHA256_Final(&context, hmac); /* finish up 2nd pass */
}
void hmac_sha384(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac) {
SHA512_State context;
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
int i;
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA384
SHA384_Init(&context); /* init context for 1st pass */
SHA384_Bytes(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
SHA384_Bytes(&context, text, text_len); /* then text of datagram */
SHA384_Final(&context, hmac); /* finish up 1st pass */
// perform outer SHA384
SHA384_Init(&context); /* init context for 2nd pass */
SHA384_Bytes(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
SHA384_Bytes(&context, hmac, SHA384_DIGEST_SIZE); /* then results of 1st hash */
SHA384_Final(&context, hmac); /* finish up 2nd pass */
}
void hmac_sha512(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac) {
SHA512_State context;
unsigned char k_ipad[KEY_IOPAD_SIZE]; /* inner padding - key XORd with ipad */
unsigned char k_opad[KEY_IOPAD_SIZE]; /* outer padding - key XORd with opad */
int i;
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < KEY_IOPAD_SIZE; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA512
SHA512_Init(&context); /* init context for 1st pass */
SHA512_Bytes(&context, k_ipad, KEY_IOPAD_SIZE); /* start with inner pad */
SHA512_Bytes(&context, text, text_len); /* then text of datagram */
SHA512_Final(&context, hmac); /* fnish up 1st pass */
// perform outer SHA512
SHA512_Init(&context); /* init context for 2nd pass */
SHA512_Bytes(&context, k_opad, KEY_IOPAD_SIZE); /* start with outer pad */
SHA512_Bytes(&context, hmac, SHA512_DIGEST_SIZE); /* then results of 1st hash */
SHA512_Final(&context, hmac); /* finish up 2nd pass */
}

29
cipher/hmac.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _CIPHER_HMAC_ALL_H
#define _CIPHER_HMAC_ALL_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define SHA1_DIGEST_SIZE 20
#define SHA224_DIGEST_SIZE 28
#define SHA256_DIGEST_SIZE 32
#define SHA384_DIGEST_SIZE 48
#define SHA512_DIGEST_SIZE 64
#define MD5_DIGEST_SIZE 16
void hmac_md5(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac);
void hmac_sha1(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac);
void hmac_sha224(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac);
void hmac_sha256(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac);
void hmac_sha384(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac);
void hmac_sha512(unsigned char *key, int key_len,
unsigned char *text, int text_len, unsigned char *hmac);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_HMAC_ALL_H */

373
cipher/md5.c Normal file
View File

@ -0,0 +1,373 @@
/* taken from RFC-1321/Appendix A.3 */
/*
* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights
* reserved.
*
* License to copy and use this software is granted provided that it is
* identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
* in all material mentioning or referencing this software or this function.
*
* License is also granted to make and use derivative works provided that such
* works are identified as "derived from the RSA Data Security, Inc. MD5
* Message-Digest Algorithm" in all material mentioning or referencing the
* derived work.
*
* RSA Data Security, Inc. makes no representations concerning either the
* merchantability of this software or the suitability of this software for
* any particular purpose. It is provided "as is" without express or implied
* warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
#include "md5.h"
/*
* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/*
* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/*
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is
* separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/*
* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void
MD5Init(//context)
MD5_CTX *context)/* context */
{
context->count[0] = context->count[1] = 0;
/*
* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/*
* MD5 block update operation. Continues an MD5 message-digest operation,
* processing another message block, and updating the context.
*/
void
MD5Update(//context, input, inputLen)
MD5_CTX *context,/* context */
unsigned char *input, /* input block */
unsigned int inputLen) /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4) inputLen << 3))
< ((UINT4) inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4) inputLen >> 29);
partLen = 64 - index;
/*
* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER) & context->buffer[index], (POINTER) input, partLen);
MD5Transform(context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform(context->state, &input[i]);
index = 0;
} else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER) & context->buffer[index], (POINTER) & input[i],
inputLen - i);
}
/*
* MD5 finalization. Ends an MD5 message-digest operation, writing the the
* message digest and zeroizing the context.
*/
void
MD5Final(//digest, context)
unsigned char digest[16], /* message digest */
MD5_CTX *context)/* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode(bits, context->count, 8);
/*
* Pad out to 56 mod 64.
*/
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update(context, PADDING, padLen);
/* Append length (before padding) */
MD5Update(context, bits, 8);
/* Store state in digest */
Encode(digest, context->state, 16);
/*
* Zeroize sensitive information.
*/
MD5_memset((POINTER) context, 0, sizeof(*context));
}
/*
* MD5 basic transformation. Transforms state based on block.
*/
static void
MD5Transform(//state, block)
UINT4 state[4],
unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3],
x[16];
Decode(x, block, 64);
/* Round 1 */
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/*
* Zeroize sensitive information.
*/
MD5_memset((POINTER) x, 0, sizeof(x));
}
/*
* Encodes input (UINT4) into output (unsigned char). Assumes len is a
* multiple of 4.
*/
static void
Encode(//output, input, len)
unsigned char *output,
UINT4 *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char) (input[i] & 0xff);
output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
}
}
/*
* Decodes input (unsigned char) into output (UINT4). Assumes len is a
* multiple of 4.
*/
static void
Decode(//output, input, len)
UINT4 *output,
unsigned char *input,
unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
(((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
}
/*
* Note: Replace "for loop" with standard memcpy if possible.
*/
static void
MD5_memcpy(//output, input, len)
POINTER output,
POINTER input,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/*
* Note: Replace "for loop" with standard memset if possible.
*/
static void
MD5_memset(//output, value, len)
POINTER output,
int value,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *) output)[i] = (char) value;
}
void MD5Calc(const unsigned char *input, unsigned int inlen, unsigned char *output)
{
MD5_CTX context;
MD5Init(&context);
// Md5 Key
static char initStr[32+1] =
{0x21, 0x45, 0x34, 0x12, 0x20, 0x85, 0x21, 0x89,
0x10, 0x20, 0x34, 0x23, 0x34, 0xa1, 0x1f, 0x13,
0x1d, 0x2d, 0x4c, 0x33, 0x39, 0xb2, 0x2c, 0x34,
0xd4, 0xb4, 0x4f, 0xff, 0x9b, 0x45, 0x3a, 0xf5, 0x00};
//MD5Update(&context, (unsigned char *)initStr, 32);
MD5Update(&context, (unsigned char *)input, inlen);
MD5Final(output, &context);
}

83
cipher/md5.h Normal file
View File

@ -0,0 +1,83 @@
/* taken from RFC-1321/Appendices A.1/A.2 */
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef _SYS_MD5_H_
#define _SYS_MD5_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef unsigned int UINT4;
typedef unsigned char UCHAR;
#ifndef PROTOTYPES
#define PROTOTYPES 1 /* jeikul modified this from 0 to 1 */
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
/* typedef unsigned long int UINT4; */
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
// The function to calculate the message digest string
// of a given string based on the MD5 algrithm.
void MD5Calc(const unsigned char *input, unsigned int inlen, unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _SYS_MD5_H_ */

472
cipher/md5key.cpp Normal file
View File

@ -0,0 +1,472 @@
#define _MD5KEY_CPP
#ifndef _REENTRANT
#define _REENTRANT /* basic 3-lines for threads */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#ifdef LINUX
#include <sys/time.h>
#endif
#include "md5.h"
#include "md5key.h"
int CalcPasswordLen(int inlen)
{
return ((inlen+15)/16)*16;
}
int MakePassword(char *output, char *input, int inlen, unsigned char *key, unsigned char *vector)
{
unsigned int keylen = strlen((char *) key);
unsigned char buf[128];
if (keylen > sizeof(buf)-16)
keylen = sizeof(buf)-16;
memset(buf, 0, sizeof(buf));
strncpy((char *) buf, (char *) key, sizeof(buf)-16);
memcpy(buf+keylen, vector, 16);
int outlen = ((inlen+15)/16)*16;
memset(output, 0, outlen);
outlen = 0;
int i=0;
unsigned char b[17], p[17];
unsigned char *c;
while (inlen > 0) {
MD5Calc(buf, keylen + 16, b);
memset(p, 0, sizeof(p));
int len = (inlen<16) ? inlen : 16;
inlen -= len;
memcpy(p, input+i, len); //input segment of 16 chars
c = (unsigned char *) (output+i); //output buffer
for (int j=0; j<16; j++)
buf[keylen+j] = c[j] = p[j] ^ b[j];
outlen += 16;
i += len;
}
return outlen;
}
/**************************************************
Function:
unlock the password by MD5 key
***************************************************/
int GetPassword(char *output, char *input, int inlen, unsigned char *key, unsigned char *vector)
{
unsigned int keylen = strlen((char *) key);
unsigned char buf[128];
if (keylen > sizeof(buf)-16)
keylen = sizeof(buf)-16;
memset(buf, 0, sizeof(buf));
strncpy((char *) buf, (char *) key, sizeof(buf)-16);
memcpy(buf+keylen, vector, 16);
int outlen = ((inlen+15)/16)*16;
memset(output, 0, outlen);
int i=0;
unsigned char b[17], c[17];
unsigned char *p;
outlen = 0;
while (inlen>0) {
MD5Calc(buf, keylen + 16, b);
memset(c, 0, sizeof(c));
int len = (inlen < 16) ? inlen : 16;
inlen -= len;
memcpy(c, input+i, len); //input segment of 16 chars
p = (unsigned char *) (output+i); //output buffer
for (int j=0; j<16; j++) {
p[j] = c[j] ^ b[j];
buf[keylen+j] = c[j];
}
outlen += 16;
i += len;
}
return outlen;
}
time_t GetExpireSec(char *expire)
{
int year;
int month;
int day;
if (sscanf(expire, "%d/%d/%d", &year, &month, &day) != 3) {
return -1;
}
struct tm time_str;
time_str.tm_year = year - 1900;
time_str.tm_mon = month - 1;
time_str.tm_mday = day;
time_str.tm_hour = 0;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
time_t expiresec = mktime(&time_str);
return expiresec;
}
unsigned long GetExpireDays(char *expire)
{
int year;
int month;
int day;
if (sscanf(expire, "%d/%d/%d", &year, &month, &day) != 3) {
//printf("error format of expire %s\n", expire);
return 0;
}
//printf("year=%04d, month=%02d, day=%02d\n", year, month, day);
time_t nowsec;
time(&nowsec);
struct tm time_str;
localtime_r(&nowsec, &time_str);
time_str.tm_hour = 0;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
nowsec = mktime(&time_str);
time_str.tm_year = year - 1900;
time_str.tm_mon = month - 1;
time_str.tm_mday = day;
time_str.tm_hour = 0;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
time_t expiresec = mktime(&time_str);
return ((expiresec >= nowsec) ? expiresec - nowsec : 0) / (60*60*24);
}
long ToUINT4(int c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return -1;
}
int GenLicenseKey(char *buf,
char *product,
char *version,
char *client,
unsigned long users,
char *expire,
char *hostid )
{
if (buf == NULL || product == NULL || version == NULL || client == NULL || expire == NULL || hostid == NULL)
return -1;
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
unsigned int rs = t.tv_nsec;
time_t nowsec = t.tv_sec;
struct tm now_str;
localtime_r(&nowsec, &now_str);
now_str.tm_hour = 0;
now_str.tm_min = 0;
now_str.tm_sec = 1;
now_str.tm_isdst= -1;
nowsec = mktime(&now_str);
unsigned char vector[17];
memset(vector, 0, sizeof(vector));
int i;
for (i = 0; i< 16; i++)
vector[i] = (unsigned char) rand_r(&rs);
if (strlen(hostid) != 8)
return -1;
long id = 0;
for (i=0; i<8; i++) {
id = id*16 + ToUINT4((unsigned char) hostid[i]);
}
unsigned char key[10];
sprintf((char *) key, "%08lx", id);
char sbuf[1024];
memset(sbuf, 0, sizeof(sbuf));
int len = 0;
memcpy(sbuf+len, vector, 16);
len += 16;
int l = strlen(product);
sbuf[len] = l;
memcpy(sbuf+len+1, product, l);
len += l+1;
l = strlen(version);
sbuf[len] = l;
memcpy(sbuf+len+1, version, l);
len += l+1;
l = strlen(client);
sbuf[len] = l;
memcpy(sbuf+len+1, client, l);
len += l+1;
unsigned long v = users;
unsigned char v1 = (v >> 24) & 0xff;
unsigned char v2 = (v >> 16) & 0xff;
unsigned char v3 = (v >> 8) & 0xff;
unsigned char v4 = v & 0xff;
sbuf[len] = v1;
sbuf[len+1] = v2;
sbuf[len+2] = v3;
sbuf[len+3] = v4;
len += 4;
long expireSec;
if (strcasecmp(expire, "Never") != 0) {
expireSec = GetExpireSec(expire);
}
else {
expireSec = -1;
}
v = expireSec;
v1 = (v >> 24) & 0xff;
v2 = (v >> 16) & 0xff;
v3 = (v >> 8) & 0xff;
v4 = v & 0xff;
sbuf[len] = v1;
sbuf[len+1] = v2;
sbuf[len+2] = v3;
sbuf[len+3] = v4;
len += 4;
v = id;
v1 = (v >> 24) & 0xff;
v2 = (v >> 16) & 0xff;
v3 = (v >> 8) & 0xff;
v4 = v & 0xff;
sbuf[len] = v1;
sbuf[len+1] = v2;
sbuf[len+2] = v3;
sbuf[len+3] = v4;
len += 4;
v = id;
v1 = (v >> 24) & 0xff;
v2 = (v >> 16) & 0xff;
v3 = (v >> 8) & 0xff;
v4 = v & 0xff;
buf[0] = v1;
buf[1] = v2;
buf[2] = v3;
buf[3] = v4;
memcpy(buf+4, vector, 16);
return MakePassword(buf+20, sbuf, len, key, vector) + 20;
}
LicenseKeyRet CheckLicenseKey(char *key, int keylen,
char *product,
char *version,
char *client,
char *hostid,
unsigned long *users,
long *expire)
{
if (keylen < 20) {
printf("CheckLicenseKey() keylen=%d, < 20\n", keylen);
return kLicenseKeyError;
}
if (((keylen-20)%16) != 0) {
printf("CheckLicenseKey() keylen=%d error\n", keylen);
return kLicenseKeyError;
}
int i;
long _id=0;
for (i=0; i<4; i++)
_id = _id*256 + (unsigned char) key[i];
char _hostid[9];
sprintf(_hostid, "%08lx", _id);
bool hostidOK=false;
if (strcmp(_hostid, hostid) == 0) {
hostidOK = true;
}
else {
printf("_hostid=%s, hostid=%s\n", _hostid, hostid);
hostidOK = false;
}
unsigned char md5key[64];
memset(md5key, 0, sizeof(md5key));
memcpy(md5key, _hostid, 8);
unsigned char vector[17];
memset(vector, 0, sizeof(vector));
memcpy(vector, key+4, 16);
char sbuf[1024];
memset(sbuf, 0, sizeof(sbuf));
GetPassword(sbuf, key+20, keylen-20, md5key, vector);
if (memcmp(vector, sbuf, 16) != 0) {
if (hostidOK) {
printf("CheckLicenseKey() vector error\n");
return kLicenseKeyError;
}
else
return kLicenseHostIDError;
}
int len = 16;
int l = (unsigned char) sbuf[len++];
char _product[64];
memset(_product, 0, sizeof(_product));
memcpy(_product, sbuf+len, l);
len += l;
l = (unsigned char) sbuf[len++];
char _version[10];
memset(_version, 0, sizeof(_version));
memcpy(_version, sbuf+len, l);
len += l;
l = (unsigned char) sbuf[len++];
char _client[256];
memset(_client, 0, sizeof(_client));
memcpy(_client, sbuf+len, l);
len += l;
unsigned long _users = 0;
for (i=0; i<4; i++)
_users = _users*256 + (unsigned char) sbuf[len++];
unsigned long _expireSec = 0;
for (i=0; i<4; i++)
_expireSec = _expireSec*256 + (unsigned char) sbuf[len++];
long _id1=0;
for (i=0; i<4; i++)
_id1 = _id1*256 + (unsigned char) sbuf[len++];
//printf("keylen=%d, len=%d\n", keylen, len);
//struct tm expire_str;
//localtime_r((time_t *)&_expireSec, &expire_str);
*users = _users;
*expire = _expireSec;
if (_id != _id1) {
printf("_id=%08x, _id1=%08x\n", _id, _id1);
hostidOK = false;
}
if (strcmp(_product, product) != 0)
return kLicenseNotThisProduct;
if (strcmp(_version, version) != 0)
return kLicenseVersionError;
if (strcmp(_client, client) != 0)
return kLicenseClientError;
time_t nowsec;
time(&nowsec);
if ((unsigned long) nowsec >= (unsigned long) _expireSec) {
printf("now=%d, expire=%u\n", nowsec, _expireSec);
return kLicenseExpireDayTimeout;
}
if (hostidOK == false) {
printf("_id=%08x, _id1=%08x, hostid=%s\n", _id, _id1, hostid);
return kLicenseHostIDError;
}
return kLicenseOK;
}
#ifdef LINUX
/*Simulate the POSIX.4 time function in Linux,but the precision is microsecond*/
int clock_gettime (int clock_id, struct timespec *ts)
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
TIMEVAL_TO_TIMESPEC(&tv, ts);
return 0;
}
#endif
/*
void main(int argc, char *argv[])
{
int i, outlen;
char *key = "88----89";
char vector[16] = {0x34, 0x5b, 0x0a, 0x9f, 0x1d, 0xfa, 0x27, 0xec, 0x48, 0x35, 0x17, 0xb5, 0x36, 0xd2, 0x6e, 0x4a};
char secret[16] = {0xb7, 0x52, 0x90, 0x5b, 0xbf, 0xb7, 0x97, 0x6f, 0x19, 0xda, 0xf6, 0xac, 0x1e, 0x9e, 0x9d, 0xe7};
char output[200], recalc[200];
if (argc != 2)
return -1;
printf("key=%s\n", key);
printf("input=%s\n", argv[1]);
outlen = MakePassword(output, argv[1], strlen(argv[1]), key, vector);
printf("Secret string: ");
for (i=0; i<outlen; i++)
printf("[%02x] ", (unsigned char) output[i]);
printf("\n\tLen=%d\n", outlen);
printf("other: ");
for (i=0; i<16; i++)
printf("[%02x] ", (unsigned char) secret[i]);
printf("\n");
GetPassword(recalc, output, outlen, key, vector);
printf("recalc=%s\n", recalc);
return 0;
}
*/

34
cipher/md5key.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef _CIPHER_MD5KEY_H_
#define _CIPHER_MD5KEY_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int CalcPasswordLen(int inlen);
int MakePassword(char *output, char *input, int inlen, unsigned char *key, unsigned char *vector);
int GetPassword(char *output, char *input, int inlen, unsigned char *key, unsigned char *vector);
enum LicenseKeyRet {
kLicenseOK = 0,
kLicenseNotThisProduct = -1,
kLicenseVersionError = -2,
kLicenseClientError = -3,
kLicenseNotEnoughtLicense = -4,
kLicenseExpireDayError = -5,
kLicenseExpireDayTimeout = -6,
kLicenseHostIDError = -7,
kLicenseKeyError = -8
};
time_t GetExpireSec(char *expire);
unsigned long GetExpireDays(char *expire);
int GenLicenseKey(char *buf, char *product, char *version, char *client, unsigned long users, char *expire, char *hostid);
LicenseKeyRet CheckLicenseKey(char *key, int keylen, char *product, char *version, char *client, char *hostid, unsigned long *users, long *expireSec);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // _CIPHER_MD5KEY_H_

325
cipher/pbkdf2_hmac.c Normal file
View File

@ -0,0 +1,325 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pbkdf2_hmac.h"
#include "sha.h"
#define KEY_IOPAD_SIZE 64
#define PUT_32BIT_MSB_FIRST(cp, value) ( \
(cp)[0] = (unsigned char)((value) >> 24), \
(cp)[1] = (unsigned char)((value) >> 16), \
(cp)[2] = (unsigned char)((value) >> 8), \
(cp)[3] = (unsigned char)(value))
typedef struct {
SHA_State ctx;
unsigned char ipad[KEY_IOPAD_SIZE]; /*!< HMAC: inner padding */
unsigned char opad[KEY_IOPAD_SIZE]; /*!< HMAC: outer padding */
} sha1_context;
void sha1_hmac_starts(sha1_context * ctx, const unsigned char *key, int keylen)
{
int i;
unsigned char sum[20];
if (keylen > 64) {
SHA_Simple(key, keylen, sum);
keylen = 20;
key = sum;
}
memset(ctx->ipad, 0x36, KEY_IOPAD_SIZE);
memset(ctx->opad, 0x5C, KEY_IOPAD_SIZE);
for (i = 0; i < keylen; i++) {
ctx->ipad[i] = (unsigned char)(ctx->ipad[i] ^ key[i]);
ctx->opad[i] = (unsigned char)(ctx->opad[i] ^ key[i]);
}
SHA_Init(&ctx->ctx);
SHA_Bytes(&ctx->ctx, ctx->ipad, KEY_IOPAD_SIZE);
}
/*
* SHA-1 HMAC process buffer
*/
void sha1_hmac_update(sha1_context * ctx, const unsigned char *input, int ilen)
{
SHA_Bytes(&ctx->ctx, input, ilen);
}
/*
* SHA-1 HMAC final digest
*/
void sha1_hmac_finish(sha1_context * ctx, unsigned char output[20])
{
unsigned char tmpbuf[20];
SHA_Final(&ctx->ctx, tmpbuf);
SHA_Init(&ctx->ctx);
SHA_Bytes(&ctx->ctx, ctx->opad, 64);
SHA_Bytes(&ctx->ctx, tmpbuf, 20);
SHA_Final(&ctx->ctx, output);
}
#ifndef min
#define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
#endif
void PKCS5_PBKDF2_HMAC(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output)
{
sha1_context ctx;
SHA_Init(&ctx.ctx);
// Size of the generated digest
unsigned char md_size = 20;
unsigned char md1[20];
unsigned char work[20];
unsigned long counter = 1;
unsigned long generated_key_length = 0;
while (generated_key_length < key_length) {
// U1 ends up in md1 and work
unsigned char c[4];
PUT_32BIT_MSB_FIRST(c, counter);
sha1_hmac_starts(&ctx, password, plen);
sha1_hmac_update(&ctx, salt, slen);
sha1_hmac_update(&ctx, c, 4);
sha1_hmac_finish(&ctx, md1);
memcpy(work, md1, md_size);
unsigned long ic = 1;
for (ic = 1; ic < iteration_count; ic++) {
// U2 ends up in md1
sha1_hmac_starts(&ctx, password, plen);
sha1_hmac_update(&ctx, md1, md_size);
sha1_hmac_finish(&ctx, md1);
// U1 xor U2
unsigned long i = 0;
for (i = 0; i < md_size; i++) {
work[i] ^= md1[i];
}
// and so on until iteration_count
}
// Copy the generated bytes to the key
unsigned long bytes_to_write =
min((key_length - generated_key_length), md_size);
memcpy(output + generated_key_length, work, bytes_to_write);
generated_key_length += bytes_to_write;
++counter;
}
}
#include "sha256.h"
// for SHA256 HMAC
typedef struct {
SHA256_State ctx;
unsigned char ipad[KEY_IOPAD_SIZE]; /*!< HMAC: inner padding */
unsigned char opad[KEY_IOPAD_SIZE]; /*!< HMAC: outer padding */
} sha2_context;
#define SHA256_DIGEST_SIZE 32
void sha2_hmac_starts(sha2_context * ctx, const unsigned char *key, int keylen)
{
int i;
unsigned char sum[SHA256_DIGEST_SIZE];
if (keylen > 64) {
SHA256_Simple(key, keylen, sum);
keylen = SHA256_DIGEST_SIZE;
key = sum;
}
memset(ctx->ipad, 0x36, KEY_IOPAD_SIZE);
memset(ctx->opad, 0x5C, KEY_IOPAD_SIZE);
for (i = 0; i < keylen; i++) {
ctx->ipad[i] = (unsigned char)(ctx->ipad[i] ^ key[i]);
ctx->opad[i] = (unsigned char)(ctx->opad[i] ^ key[i]);
}
SHA256_Init(&ctx->ctx);
SHA256_Bytes(&ctx->ctx, ctx->ipad, KEY_IOPAD_SIZE);
}
/*
* SHA-2 HMAC process buffer
*/
void sha2_hmac_update(sha2_context * ctx, const unsigned char *input, int ilen)
{
SHA256_Bytes(&ctx->ctx, input, ilen);
}
/*
* SHA-2 HMAC final digest
*/
void sha2_hmac_finish(sha2_context * ctx, unsigned char output[20])
{
unsigned char tmpbuf[SHA256_DIGEST_SIZE];
SHA256_Final(&ctx->ctx, tmpbuf);
SHA256_Init(&ctx->ctx);
SHA256_Bytes(&ctx->ctx, ctx->opad, 64);
SHA256_Bytes(&ctx->ctx, tmpbuf, SHA256_DIGEST_SIZE);
SHA256_Final(&ctx->ctx, output);
}
void PKCS5_PBKDF2_HMAC2(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output)
{
sha2_context ctx;
SHA256_Init(&ctx.ctx);
// Size of the generated digest
unsigned char md_size = SHA256_DIGEST_SIZE;
unsigned char md1[SHA256_DIGEST_SIZE];
unsigned char work[SHA256_DIGEST_SIZE];
unsigned long counter = 1;
unsigned long generated_key_length = 0;
while (generated_key_length < key_length) {
// U1 ends up in md1 and work
unsigned char c[4];
PUT_32BIT_MSB_FIRST(c, counter);
sha2_hmac_starts(&ctx, password, plen);
sha2_hmac_update(&ctx, salt, slen);
sha2_hmac_update(&ctx, c, 4);
sha2_hmac_finish(&ctx, md1);
memcpy(work, md1, md_size);
unsigned long ic = 1;
for (ic = 1; ic < iteration_count; ic++) {
// U2 ends up in md1
sha2_hmac_starts(&ctx, password, plen);
sha2_hmac_update(&ctx, md1, md_size);
sha2_hmac_finish(&ctx, md1);
// U1 xor U2
unsigned long i = 0;
for (i = 0; i < md_size; i++) {
work[i] ^= md1[i];
}
// and so on until iteration_count
}
// Copy the generated bytes to the key
unsigned long bytes_to_write =
min((key_length - generated_key_length), md_size);
memcpy(output + generated_key_length, work, bytes_to_write);
generated_key_length += bytes_to_write;
++counter;
}
}
#include "sha512.h"
// for SHA512 HMAC
typedef struct {
SHA512_State ctx;
unsigned char ipad[KEY_IOPAD_SIZE]; /*!< HMAC: inner padding */
unsigned char opad[KEY_IOPAD_SIZE]; /*!< HMAC: outer padding */
} sha5_context;
#define SHA512_DIGEST_SIZE 64
void sha5_hmac_starts(sha5_context * ctx, const unsigned char *key, int keylen)
{
int i;
unsigned char sum[SHA512_DIGEST_SIZE];
if (keylen > 64) {
SHA512_Simple(key, keylen, sum);
keylen = SHA512_DIGEST_SIZE;
key = sum;
}
memset(ctx->ipad, 0x36, KEY_IOPAD_SIZE);
memset(ctx->opad, 0x5C, KEY_IOPAD_SIZE);
for (i = 0; i < keylen; i++) {
ctx->ipad[i] = (unsigned char)(ctx->ipad[i] ^ key[i]);
ctx->opad[i] = (unsigned char)(ctx->opad[i] ^ key[i]);
}
SHA512_Init(&ctx->ctx);
SHA512_Bytes(&ctx->ctx, ctx->ipad, KEY_IOPAD_SIZE);
}
/*
* SHA-2 HMAC process buffer
*/
void sha5_hmac_update(sha5_context * ctx, const unsigned char *input, int ilen)
{
SHA512_Bytes(&ctx->ctx, input, ilen);
}
/*
* SHA-2 HMAC final digest
*/
void sha5_hmac_finish(sha5_context * ctx, unsigned char output[20])
{
unsigned char tmpbuf[SHA512_DIGEST_SIZE];
SHA512_Final(&ctx->ctx, tmpbuf);
SHA512_Init(&ctx->ctx);
SHA512_Bytes(&ctx->ctx, ctx->opad, 64);
SHA512_Bytes(&ctx->ctx, tmpbuf, SHA512_DIGEST_SIZE);
SHA512_Final(&ctx->ctx, output);
}
void PKCS5_PBKDF2_HMAC5(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output)
{
sha5_context ctx;
SHA512_Init(&ctx.ctx);
// Size of the generated digest
unsigned char md_size = SHA512_DIGEST_SIZE;
unsigned char md1[SHA512_DIGEST_SIZE];
unsigned char work[SHA512_DIGEST_SIZE];
unsigned long counter = 1;
unsigned long generated_key_length = 0;
while (generated_key_length < key_length) {
// U1 ends up in md1 and work
unsigned char c[4];
PUT_32BIT_MSB_FIRST(c, counter);
sha5_hmac_starts(&ctx, password, plen);
sha5_hmac_update(&ctx, salt, slen);
sha5_hmac_update(&ctx, c, 4);
sha5_hmac_finish(&ctx, md1);
memcpy(work, md1, md_size);
unsigned long ic = 1;
for (ic = 1; ic < iteration_count; ic++) {
// U2 ends up in md1
sha5_hmac_starts(&ctx, password, plen);
sha5_hmac_update(&ctx, md1, md_size);
sha5_hmac_finish(&ctx, md1);
// U1 xor U2
unsigned long i = 0;
for (i = 0; i < md_size; i++) {
work[i] ^= md1[i];
}
// and so on until iteration_count
}
// Copy the generated bytes to the key
unsigned long bytes_to_write =
min((key_length - generated_key_length), md_size);
memcpy(output + generated_key_length, work, bytes_to_write);
generated_key_length += bytes_to_write;
++counter;
}
}

21
cipher/pbkdf2_hmac.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _CIPHER_PKCS5_PBKDF2_HMAC_H
#define _CIPHER_PKCS5_PBKDF2_HMAC_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void PKCS5_PBKDF2_HMAC(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output);
void PKCS5_PBKDF2_HMAC2(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output);
void PKCS5_PBKDF2_HMAC5(const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
const unsigned long iteration_count, const unsigned long key_length,
unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // _CIPHER_PKCS5_PBKDF2_HMAC_H

42
cipher/rc4.c Normal file
View File

@ -0,0 +1,42 @@
#include "rc4.h"
#define RC4_SIZE 256
void rc4_setup(unsigned char *s,
unsigned char *key, unsigned int Len) {
int i = 0, j = 0;
char k[RC4_SIZE] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < RC4_SIZE; i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i = 0; i < RC4_SIZE; i++) {
j = (j + s[i] + k[i]) % RC4_SIZE;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
void rc4_crypt(unsigned char *s,
unsigned char *data, unsigned int Len) {
int i = 0, j = 0, t = 0;
unsigned int k = 0;
unsigned char tmp;
for (k = 0; k < Len; k++) {
i = (i + 1) % RC4_SIZE;
j = (j + s[i]) % RC4_SIZE;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
t = (s[i] + s[j]) % RC4_SIZE;
data[k] ^= s[t];
}
}
void RC4_Sample(unsigned char *key, int key_len,
unsigned char *data, int data_len) {
char sbox[RC4_SIZE] = { 0 };
rc4_setup(sbox, key, key_len);
rc4_crypt(sbox, data, data_len);
}

11
cipher/rc4.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef _CIPHER_RC4_H
#define _CIPHER_RC4_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void RC4_Sample(unsigned char *key, int key_len,
unsigned char *data, int data_len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // _CIPHER_RC4_H

19
cipher/rsa/Makefile Normal file
View File

@ -0,0 +1,19 @@
OBJ=asn1.o os_unix.o common.o wpabuf.o wpa_debug.o rsa.o bignum.o base64.o
all:test_rsa libuser_rsa.a
test_rsa: $(OBJ) test_rsa.o
gcc -o $@ $^
libuser_rsa.a: $(OBJ) user_rsa.o
ar rus $@ $^
%.o:%.c
gcc -DCONFIG_USE_INTTYPES_H -DCONFIG_INTERNAL_LIBTOMMATH -g -c $<
key:
openssl genrsa -out privkey 464
openssl rsa -in privkey -pubout -out pubkey
clean:
rm -rf *.o test_rsa libuser_rsa.a

19
cipher/rsa/Makefile.aix Normal file
View File

@ -0,0 +1,19 @@
OBJ=asn1.o os_unix.o common.o wpabuf.o wpa_debug.o rsa.o bignum.o base64.o
all:test_rsa libuser_rsa.a
test_rsa: $(OBJ) test_rsa.o
xlc -o $@ $^
libuser_rsa.a: $(OBJ) user_rsa.o
ar rus $@ $^
%.o:%.c
xlc -D__AIX__ -DCONFIG_INTERNAL_LIBTOMMATH -g -c $<
key:
openssl genrsa -out privkey 464
openssl rsa -in privkey -pubout -out pubkey
clean:
rm -rf *.o test_rsa libuser_rsa.a

19
cipher/rsa/Makefile.hp Normal file
View File

@ -0,0 +1,19 @@
OBJ=asn1.o os_unix.o common.o wpabuf.o wpa_debug.o rsa.o bignum.o base64.o
all:test_rsa libuser_rsa.a
test_rsa: $(OBJ) test_rsa.o
cc -o $@ $^
libuser_rsa.a: $(OBJ) user_rsa.o
ar rus $@ $^
%.o:%.c
cc -DHPUX -DCONFIG_NO_INLINE -DCONFIG_INTERNAL_LIBTOMMATH -g -c $<
key:
openssl genrsa -out privkey 464
openssl rsa -in privkey -pubout -out pubkey
clean:
rm -rf *.o test_rsa libuser_rsa.a

19
cipher/rsa/Makefile.linux Normal file
View File

@ -0,0 +1,19 @@
OBJ=asn1.o os_unix.o common.o wpabuf.o wpa_debug.o rsa.o bignum.o base64.o
all:test_rsa libuser_rsa.a
test_rsa: $(OBJ) test_rsa.o
gcc -o $@ $^
libuser_rsa.a: $(OBJ) user_rsa.o
ar rus $@ $^
%.o:%.c
gcc -fPIC -DCONFIG_INTERNAL_LIBTOMMATH -g -c $<
key:
openssl genrsa -out privkey 464
openssl rsa -in privkey -pubout -out pubkey
clean:
rm -rf *.o test_rsa libuser_rsa.a

212
cipher/rsa/asn1.c Normal file
View File

@ -0,0 +1,212 @@
/*
* ASN.1 DER parsing
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "asn1.h"
int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr)
{
const u8 *pos, *end;
u8 tmp;
os_memset(hdr, 0, sizeof(*hdr));
pos = buf;
end = buf + len;
hdr->identifier = *pos++;
hdr->class = hdr->identifier >> 6;
hdr->constructed = !!(hdr->identifier & (1 << 5));
if ((hdr->identifier & 0x1f) == 0x1f) {
hdr->tag = 0;
do {
if (pos >= end) {
wpa_printf(MSG_DEBUG, "ASN.1: Identifier "
"underflow");
return -1;
}
tmp = *pos++;
wpa_printf(MSG_MSGDUMP, "ASN.1: Extended tag data: "
"0x%02x", tmp);
hdr->tag = (hdr->tag << 7) | (tmp & 0x7f);
} while (tmp & 0x80);
} else
hdr->tag = hdr->identifier & 0x1f;
tmp = *pos++;
if (tmp & 0x80) {
if (tmp == 0xff) {
wpa_printf(MSG_DEBUG, "ASN.1: Reserved length "
"value 0xff used");
return -1;
}
tmp &= 0x7f; /* number of subsequent octets */
hdr->length = 0;
if (tmp > 4) {
wpa_printf(MSG_DEBUG, "ASN.1: Too long length field");
return -1;
}
while (tmp--) {
if (pos >= end) {
wpa_printf(MSG_DEBUG, "ASN.1: Length "
"underflow");
return -1;
}
hdr->length = (hdr->length << 8) | *pos++;
}
} else {
/* Short form - length 0..127 in one octet */
hdr->length = tmp;
}
if (end < pos || hdr->length > (unsigned int) (end - pos)) {
wpa_printf(MSG_DEBUG, "ASN.1: Contents underflow");
return -1;
}
hdr->payload = pos;
return 0;
}
int asn1_parse_oid(const u8 *buf, size_t len, struct asn1_oid *oid)
{
const u8 *pos, *end;
unsigned long val;
u8 tmp;
os_memset(oid, 0, sizeof(*oid));
pos = buf;
end = buf + len;
while (pos < end) {
val = 0;
do {
if (pos >= end)
return -1;
tmp = *pos++;
val = (val << 7) | (tmp & 0x7f);
} while (tmp & 0x80);
if (oid->len >= ASN1_MAX_OID_LEN) {
wpa_printf(MSG_DEBUG, "ASN.1: Too long OID value");
return -1;
}
if (oid->len == 0) {
/*
* The first octet encodes the first two object
* identifier components in (X*40) + Y formula.
* X = 0..2.
*/
oid->oid[0] = val / 40;
if (oid->oid[0] > 2)
oid->oid[0] = 2;
oid->oid[1] = val - oid->oid[0] * 40;
oid->len = 2;
} else
oid->oid[oid->len++] = val;
}
return 0;
}
int asn1_get_oid(const u8 *buf, size_t len, struct asn1_oid *oid,
const u8 **next)
{
struct asn1_hdr hdr;
if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0)
return -1;
if (hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_OID) {
wpa_printf(MSG_DEBUG, "ASN.1: Expected OID - found class %d "
"tag 0x%x", hdr.class, hdr.tag);
return -1;
}
*next = hdr.payload + hdr.length;
return asn1_parse_oid(hdr.payload, hdr.length, oid);
}
void asn1_oid_to_str(struct asn1_oid *oid, char *buf, size_t len)
{
char *pos = buf;
size_t i;
int ret;
if (len == 0)
return;
buf[0] = '\0';
for (i = 0; i < oid->len; i++) {
ret = os_snprintf(pos, buf + len - pos,
"%s%lu",
i == 0 ? "" : ".", oid->oid[i]);
if (ret < 0 || ret >= buf + len - pos)
break;
pos += ret;
}
buf[len - 1] = '\0';
}
static u8 rotate_bits(u8 octet)
{
int i;
u8 res;
res = 0;
for (i = 0; i < 8; i++) {
res <<= 1;
if (octet & 1)
res |= 1;
octet >>= 1;
}
return res;
}
unsigned long asn1_bit_string_to_long(const u8 *buf, size_t len)
{
unsigned long val = 0;
const u8 *pos = buf;
/* BER requires that unused bits are zero, so we can ignore the number
* of unused bits */
pos++;
if (len >= 2)
val |= rotate_bits(*pos++);
if (len >= 3)
val |= ((unsigned long) rotate_bits(*pos++)) << 8;
if (len >= 4)
val |= ((unsigned long) rotate_bits(*pos++)) << 16;
if (len >= 5)
val |= ((unsigned long) rotate_bits(*pos++)) << 24;
if (len >= 6)
wpa_printf(MSG_DEBUG, "X509: %s - some bits ignored "
"(BIT STRING length %lu)",
__func__, (unsigned long) len);
return val;
}

72
cipher/rsa/asn1.h Normal file
View File

@ -0,0 +1,72 @@
/*
* ASN.1 DER parsing
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef ASN1_H
#define ASN1_H
#define ASN1_TAG_EOC 0x00 /* not used with DER */
#define ASN1_TAG_BOOLEAN 0x01
#define ASN1_TAG_INTEGER 0x02
#define ASN1_TAG_BITSTRING 0x03
#define ASN1_TAG_OCTETSTRING 0x04
#define ASN1_TAG_NULL 0x05
#define ASN1_TAG_OID 0x06
#define ASN1_TAG_OBJECT_DESCRIPTOR 0x07 /* not yet parsed */
#define ASN1_TAG_EXTERNAL 0x08 /* not yet parsed */
#define ASN1_TAG_REAL 0x09 /* not yet parsed */
#define ASN1_TAG_ENUMERATED 0x0A /* not yet parsed */
#define ASN1_TAG_UTF8STRING 0x0C /* not yet parsed */
#define ANS1_TAG_RELATIVE_OID 0x0D
#define ASN1_TAG_SEQUENCE 0x10 /* shall be constructed */
#define ASN1_TAG_SET 0x11
#define ASN1_TAG_NUMERICSTRING 0x12 /* not yet parsed */
#define ASN1_TAG_PRINTABLESTRING 0x13
#define ASN1_TAG_TG1STRING 0x14 /* not yet parsed */
#define ASN1_TAG_VIDEOTEXSTRING 0x15 /* not yet parsed */
#define ASN1_TAG_IA5STRING 0x16
#define ASN1_TAG_UTCTIME 0x17
#define ASN1_TAG_GENERALIZEDTIME 0x18 /* not yet parsed */
#define ASN1_TAG_GRAPHICSTRING 0x19 /* not yet parsed */
#define ASN1_TAG_VISIBLESTRING 0x1A
#define ASN1_TAG_GENERALSTRING 0x1B /* not yet parsed */
#define ASN1_TAG_UNIVERSALSTRING 0x1C /* not yet parsed */
#define ASN1_TAG_BMPSTRING 0x1D /* not yet parsed */
#define ASN1_CLASS_UNIVERSAL 0
#define ASN1_CLASS_APPLICATION 1
#define ASN1_CLASS_CONTEXT_SPECIFIC 2
#define ASN1_CLASS_PRIVATE 3
struct asn1_hdr {
const u8 *payload;
u8 identifier, class, constructed;
unsigned int tag, length;
};
#define ASN1_MAX_OID_LEN 20
struct asn1_oid {
unsigned long oid[ASN1_MAX_OID_LEN];
size_t len;
};
int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr);
int asn1_parse_oid(const u8 *buf, size_t len, struct asn1_oid *oid);
int asn1_get_oid(const u8 *buf, size_t len, struct asn1_oid *oid,
const u8 **next);
void asn1_oid_to_str(struct asn1_oid *oid, char *buf, size_t len);
unsigned long asn1_bit_string_to_long(const u8 *buf, size_t len);
#endif /* ASN1_H */

154
cipher/rsa/base64.c Normal file
View File

@ -0,0 +1,154 @@
/*
* Base64 encoding/decoding (RFC1341)
* Copyright (c) 2005, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "os.h"
#include "base64.h"
static const unsigned char base64_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* base64_encode - Base64 encode
* @src: Data to be encoded
* @len: Length of the data to be encoded
* @out_len: Pointer to output length variable, or %NULL if not used
* Returns: Allocated buffer of out_len bytes of encoded data,
* or %NULL on failure
*
* Caller is responsible for freeing the returned buffer. Returned buffer is
* nul terminated to make it easier to use as a C string. The nul terminator is
* not included in out_len.
*/
unsigned char * base64_encode(const unsigned char *src, size_t len,
size_t *out_len)
{
unsigned char *out, *pos;
const unsigned char *end, *in;
size_t olen;
int line_len;
olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
olen += olen / 72; /* line feeds */
olen++; /* nul termination */
if (olen < len)
return NULL; /* integer overflow */
out = os_malloc(olen);
if (out == NULL)
return NULL;
end = src + len;
in = src;
pos = out;
line_len = 0;
while (end - in >= 3) {
*pos++ = base64_table[in[0] >> 2];
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
*pos++ = base64_table[in[2] & 0x3f];
in += 3;
line_len += 4;
if (line_len >= 72) {
*pos++ = '\n';
line_len = 0;
}
}
if (end - in) {
*pos++ = base64_table[in[0] >> 2];
if (end - in == 1) {
*pos++ = base64_table[(in[0] & 0x03) << 4];
*pos++ = '=';
} else {
*pos++ = base64_table[((in[0] & 0x03) << 4) |
(in[1] >> 4)];
*pos++ = base64_table[(in[1] & 0x0f) << 2];
}
*pos++ = '=';
line_len += 4;
}
if (line_len)
*pos++ = '\n';
*pos = '\0';
if (out_len)
*out_len = pos - out;
return out;
}
/**
* base64_decode - Base64 decode
* @src: Data to be decoded
* @len: Length of the data to be decoded
* @out_len: Pointer to output length variable
* Returns: Allocated buffer of out_len bytes of decoded data,
* or %NULL on failure
*
* Caller is responsible for freeing the returned buffer.
*/
unsigned char * base64_decode(const unsigned char *src, size_t len,
size_t *out_len)
{
unsigned char dtable[256], *out, *pos, in[4], block[4], tmp;
size_t i, count, olen;
os_memset(dtable, 0x80, 256);
for (i = 0; i < sizeof(base64_table) - 1; i++)
dtable[base64_table[i]] = (unsigned char) i;
dtable['='] = 0;
count = 0;
for (i = 0; i < len; i++) {
if (dtable[src[i]] != 0x80)
count++;
}
if (count == 0 || count % 4)
return NULL;
olen = count / 4 * 3;
pos = out = os_malloc(olen);
if (out == NULL)
return NULL;
count = 0;
for (i = 0; i < len; i++) {
tmp = dtable[src[i]];
if (tmp == 0x80)
continue;
in[count] = src[i];
block[count] = tmp;
count++;
if (count == 4) {
*pos++ = (block[0] << 2) | (block[1] >> 4);
*pos++ = (block[1] << 4) | (block[2] >> 2);
*pos++ = (block[2] << 6) | block[3];
count = 0;
}
}
if (pos > out) {
if (in[2] == '=')
pos -= 2;
else if (in[3] == '=')
pos--;
}
*out_len = pos - out;
return out;
}

31
cipher/rsa/base64.h Normal file
View File

@ -0,0 +1,31 @@
/*
* Base64 encoding/decoding (RFC1341)
* Copyright (c) 2005, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef BASE64_H
#define BASE64_h
#ifdef __cplusplus
extern "C"{
#endif
unsigned char * base64_encode(const unsigned char *src, size_t len,
size_t *out_len);
unsigned char * base64_decode(const unsigned char *src, size_t len,
size_t *out_len);
#ifdef __cplusplus
}
#endif
#endif /* BASE64_H */

230
cipher/rsa/bignum.c Normal file
View File

@ -0,0 +1,230 @@
/*
* Big number math
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "bignum.h"
#ifdef CONFIG_INTERNAL_LIBTOMMATH
#include "libtommath.c"
#else /* CONFIG_INTERNAL_LIBTOMMATH */
#include <tommath.h>
#endif /* CONFIG_INTERNAL_LIBTOMMATH */
/*
* The current version is just a wrapper for LibTomMath library, so
* struct bignum is just typecast to mp_int.
*/
/**
* bignum_init - Allocate memory for bignum
* Returns: Pointer to allocated bignum or %NULL on failure
*/
struct bignum * bignum_init(void)
{
struct bignum *n = os_zalloc(sizeof(mp_int));
if (n == NULL)
return NULL;
if (mp_init((mp_int *) n) != MP_OKAY) {
os_free(n);
n = NULL;
}
return n;
}
/**
* bignum_deinit - Free bignum
* @n: Bignum from bignum_init()
*/
void bignum_deinit(struct bignum *n)
{
if (n) {
mp_clear((mp_int *) n);
os_free(n);
}
}
/**
* bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer
* @n: Bignum from bignum_init()
* Returns: Length of n if written to a binary buffer
*/
size_t bignum_get_unsigned_bin_len(struct bignum *n)
{
return mp_unsigned_bin_size((mp_int *) n);
}
/**
* bignum_get_unsigned_bin - Set binary buffer to unsigned bignum
* @n: Bignum from bignum_init()
* @buf: Buffer for the binary number
* @len: Length of the buffer, can be %NULL if buffer is known to be long
* enough. Set to used buffer length on success if not %NULL.
* Returns: 0 on success, -1 on failure
*/
int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len)
{
size_t need = mp_unsigned_bin_size((mp_int *) n);
if (len && need > *len) {
*len = need;
return -1;
}
if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
if (len)
*len = need;
return 0;
}
/**
* bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer
* @n: Bignum from bignum_init(); to be set to the given value
* @buf: Buffer with unsigned binary value
* @len: Length of buf in octets
* Returns: 0 on success, -1 on failure
*/
int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len)
{
if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
return 0;
}
/**
* bignum_cmp - Signed comparison
* @a: Bignum from bignum_init()
* @b: Bignum from bignum_init()
* Returns: 0 on success, -1 on failure
*/
int bignum_cmp(const struct bignum *a, const struct bignum *b)
{
return mp_cmp((mp_int *) a, (mp_int *) b);
}
/**
* bignum_cmd_d - Compare bignum to standard integer
* @a: Bignum from bignum_init()
* @b: Small integer
* Returns: 0 on success, -1 on failure
*/
int bignum_cmp_d(const struct bignum *a, unsigned long b)
{
return mp_cmp_d((mp_int *) a, b);
}
/**
* bignum_add - c = a + b
* @a: Bignum from bignum_init()
* @b: Bignum from bignum_init()
* @c: Bignum from bignum_init(); used to store the result of a + b
* Returns: 0 on success, -1 on failure
*/
int bignum_add(const struct bignum *a, const struct bignum *b,
struct bignum *c)
{
if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
return 0;
}
/**
* bignum_sub - c = a - b
* @a: Bignum from bignum_init()
* @b: Bignum from bignum_init()
* @c: Bignum from bignum_init(); used to store the result of a - b
* Returns: 0 on success, -1 on failure
*/
int bignum_sub(const struct bignum *a, const struct bignum *b,
struct bignum *c)
{
if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
return 0;
}
/**
* bignum_mul - c = a * b
* @a: Bignum from bignum_init()
* @b: Bignum from bignum_init()
* @c: Bignum from bignum_init(); used to store the result of a * b
* Returns: 0 on success, -1 on failure
*/
int bignum_mul(const struct bignum *a, const struct bignum *b,
struct bignum *c)
{
if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
return 0;
}
/**
* bignum_mulmod - d = a * b (mod c)
* @a: Bignum from bignum_init()
* @b: Bignum from bignum_init()
* @c: Bignum from bignum_init(); modulus
* @d: Bignum from bignum_init(); used to store the result of a * b (mod c)
* Returns: 0 on success, -1 on failure
*/
int bignum_mulmod(const struct bignum *a, const struct bignum *b,
const struct bignum *c, struct bignum *d)
{
if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d)
!= MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
return 0;
}
/**
* bignum_exptmod - Modular exponentiation: d = a^b (mod c)
* @a: Bignum from bignum_init(); base
* @b: Bignum from bignum_init(); exponent
* @c: Bignum from bignum_init(); modulus
* @d: Bignum from bignum_init(); used to store the result of a^b (mod c)
* Returns: 0 on success, -1 on failure
*/
int bignum_exptmod(const struct bignum *a, const struct bignum *b,
const struct bignum *c, struct bignum *d)
{
if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d)
!= MP_OKAY) {
wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
return -1;
}
return 0;
}

38
cipher/rsa/bignum.h Normal file
View File

@ -0,0 +1,38 @@
/*
* Big number math
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef BIGNUM_H
#define BIGNUM_H
struct bignum;
struct bignum * bignum_init(void);
void bignum_deinit(struct bignum *n);
size_t bignum_get_unsigned_bin_len(struct bignum *n);
int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len);
int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len);
int bignum_cmp(const struct bignum *a, const struct bignum *b);
int bignum_cmp_d(const struct bignum *a, unsigned long b);
int bignum_add(const struct bignum *a, const struct bignum *b,
struct bignum *c);
int bignum_sub(const struct bignum *a, const struct bignum *b,
struct bignum *c);
int bignum_mul(const struct bignum *a, const struct bignum *b,
struct bignum *c);
int bignum_mulmod(const struct bignum *a, const struct bignum *b,
const struct bignum *c, struct bignum *d);
int bignum_exptmod(const struct bignum *a, const struct bignum *b,
const struct bignum *c, struct bignum *d);
#endif /* BIGNUM_H */

105
cipher/rsa/build_config.h Normal file
View File

@ -0,0 +1,105 @@
/*
* wpa_supplicant/hostapd - Build time configuration defines
* Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*
* This header file can be used to define configuration defines that were
* originally defined in Makefile. This is mainly meant for IDE use or for
* systems that do not have suitable 'make' tool. In these cases, it may be
* easier to have a single place for defining all the needed C pre-processor
* defines.
*/
#ifndef BUILD_CONFIG_H
#define BUILD_CONFIG_H
/* Insert configuration defines, e.g., #define EAP_MD5, here, if needed. */
#ifdef CONFIG_WIN32_DEFAULTS
#define CONFIG_NATIVE_WINDOWS
#define CONFIG_ANSI_C_EXTRA
#define CONFIG_WINPCAP
#define IEEE8021X_EAPOL
#define PKCS12_FUNCS
#define PCSC_FUNCS
#define CONFIG_CTRL_IFACE
#define CONFIG_CTRL_IFACE_NAMED_PIPE
#define CONFIG_DRIVER_NDIS
#define CONFIG_NDIS_EVENTS_INTEGRATED
#define CONFIG_DEBUG_FILE
#define EAP_MD5
#define EAP_TLS
#define EAP_MSCHAPv2
#define EAP_PEAP
#define EAP_TTLS
#define EAP_GTC
#define EAP_OTP
#define EAP_LEAP
#define EAP_TNC
#define _CRT_SECURE_NO_DEPRECATE
#ifdef USE_INTERNAL_CRYPTO
#define CONFIG_TLS_INTERNAL_CLIENT
#define CONFIG_INTERNAL_LIBTOMMATH
#define CONFIG_CRYPTO_INTERNAL
#endif /* USE_INTERNAL_CRYPTO */
#endif /* CONFIG_WIN32_DEFAULTS */
#ifdef __SYMBIAN32__
#define OS_NO_C_LIB_DEFINES
#define CONFIG_ANSI_C_EXTRA
#define CONFIG_NO_WPA_MSG
#define CONFIG_NO_HOSTAPD_LOGGER
#define CONFIG_NO_STDOUT_DEBUG
#define CONFIG_BACKEND_FILE
#define CONFIG_INTERNAL_LIBTOMMATH
#define CONFIG_CRYPTO_INTERNAL
#define IEEE8021X_EAPOL
#define PKCS12_FUNCS
#define EAP_MD5
#define EAP_TLS
#define EAP_MSCHAPv2
#define EAP_PEAP
#define EAP_TTLS
#define EAP_GTC
#define EAP_OTP
#define EAP_LEAP
#define EAP_FAST
#endif /* __SYMBIAN32__ */
#ifdef CONFIG_XCODE_DEFAULTS
#define CONFIG_DRIVER_OSX
#define CONFIG_BACKEND_FILE
#define IEEE8021X_EAPOL
#define PKCS12_FUNCS
#define CONFIG_CTRL_IFACE
#define CONFIG_CTRL_IFACE_UNIX
#define CONFIG_DEBUG_FILE
#define EAP_MD5
#define EAP_TLS
#define EAP_MSCHAPv2
#define EAP_PEAP
#define EAP_TTLS
#define EAP_GTC
#define EAP_OTP
#define EAP_LEAP
#define EAP_TNC
#define CONFIG_WPS
#define EAP_WSC
#ifdef USE_INTERNAL_CRYPTO
#define CONFIG_TLS_INTERNAL_CLIENT
#define CONFIG_INTERNAL_LIBTOMMATH
#define CONFIG_CRYPTO_INTERNAL
#endif /* USE_INTERNAL_CRYPTO */
#endif /* CONFIG_XCODE_DEFAULTS */
#endif /* BUILD_CONFIG_H */

333
cipher/rsa/common.c Normal file
View File

@ -0,0 +1,333 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
static int hex2num(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
static int hex2byte(const char *hex)
{
int a, b;
a = hex2num(*hex++);
if (a < 0)
return -1;
b = hex2num(*hex++);
if (b < 0)
return -1;
return (a << 4) | b;
}
/**
* hwaddr_aton - Convert ASCII string to MAC address
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
*/
int hwaddr_aton(const char *txt, u8 *addr)
{
int i;
for (i = 0; i < 6; i++) {
int a, b;
a = hex2num(*txt++);
if (a < 0)
return -1;
b = hex2num(*txt++);
if (b < 0)
return -1;
*addr++ = (a << 4) | b;
if (i < 5 && *txt++ != ':')
return -1;
}
return 0;
}
/**
* hexstr2bin - Convert ASCII hex string into binary data
* @hex: ASCII hex string (e.g., "01ab")
* @buf: Buffer for the binary data
* @len: Length of the text to convert in bytes (of buf); hex will be double
* this size
* Returns: 0 on success, -1 on failure (invalid hex string)
*/
int hexstr2bin(const char *hex, u8 *buf, size_t len)
{
size_t i;
int a;
const char *ipos = hex;
u8 *opos = buf;
for (i = 0; i < len; i++) {
a = hex2byte(ipos);
if (a < 0)
return -1;
*opos++ = a;
ipos += 2;
}
return 0;
}
/**
* inc_byte_array - Increment arbitrary length byte array by one
* @counter: Pointer to byte array
* @len: Length of the counter in bytes
*
* This function increments the last byte of the counter by one and continues
* rolling over to more significant bytes if the byte was incremented from
* 0xff to 0x00.
*/
void inc_byte_array(u8 *counter, size_t len)
{
int pos = len - 1;
while (pos >= 0) {
counter[pos]++;
if (counter[pos] != 0)
break;
pos--;
}
}
void wpa_get_ntp_timestamp(u8 *buf)
{
struct os_time now;
u32 sec, usec;
be32 tmp;
/* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
os_get_time(&now);
sec = now.sec + 2208988800U; /* Epoch to 1900 */
/* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
usec = now.usec;
usec = 4295 * usec - (usec >> 5) - (usec >> 9);
tmp = host_to_be32(sec);
os_memcpy(buf, (u8 *) &tmp, 4);
tmp = host_to_be32(usec);
os_memcpy(buf + 4, (u8 *) &tmp, 4);
}
static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
size_t len, int uppercase)
{
size_t i;
char *pos = buf, *end = buf + buf_size;
int ret;
if (buf_size == 0)
return 0;
for (i = 0; i < len; i++) {
ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
data[i]);
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return pos - buf;
}
pos += ret;
}
end[-1] = '\0';
return pos - buf;
}
/**
* wpa_snprintf_hex - Print data as a hex string into a buffer
* @buf: Memory area to use as the output buffer
* @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
* @data: Data to be printed
* @len: Length of data in bytes
* Returns: Number of bytes written
*/
int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
{
return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
}
/**
* wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
* @buf: Memory area to use as the output buffer
* @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
* @data: Data to be printed
* @len: Length of data in bytes
* Returns: Number of bytes written
*/
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
size_t len)
{
return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
}
#ifdef CONFIG_ANSI_C_EXTRA
#ifdef _WIN32_WCE
void perror(const char *s)
{
wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
s, (int) GetLastError());
}
#endif /* _WIN32_WCE */
int optind = 1;
int optopt;
char *optarg;
int getopt(int argc, char *const argv[], const char *optstring)
{
static int optchr = 1;
char *cp;
if (optchr == 1) {
if (optind >= argc) {
/* all arguments processed */
return EOF;
}
if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
/* no option characters */
return EOF;
}
}
if (os_strcmp(argv[optind], "--") == 0) {
/* no more options */
optind++;
return EOF;
}
optopt = argv[optind][optchr];
cp = os_strchr(optstring, optopt);
if (cp == NULL || optopt == ':') {
if (argv[optind][++optchr] == '\0') {
optchr = 1;
optind++;
}
return '?';
}
if (cp[1] == ':') {
/* Argument required */
optchr = 1;
if (argv[optind][optchr + 1]) {
/* No space between option and argument */
optarg = &argv[optind++][optchr + 1];
} else if (++optind >= argc) {
/* option requires an argument */
return '?';
} else {
/* Argument in the next argv */
optarg = argv[optind++];
}
} else {
/* No argument */
if (argv[optind][++optchr] == '\0') {
optchr = 1;
optind++;
}
optarg = NULL;
}
return *cp;
}
#endif /* CONFIG_ANSI_C_EXTRA */
#ifdef CONFIG_NATIVE_WINDOWS
/**
* wpa_unicode2ascii_inplace - Convert unicode string into ASCII
* @str: Pointer to string to convert
*
* This function converts a unicode string to ASCII using the same
* buffer for output. If UNICODE is not set, the buffer is not
* modified.
*/
void wpa_unicode2ascii_inplace(TCHAR *str)
{
#ifdef UNICODE
char *dst = (char *) str;
while (*str)
*dst++ = (char) *str++;
*dst = '\0';
#endif /* UNICODE */
}
TCHAR * wpa_strdup_tchar(const char *str)
{
#ifdef UNICODE
TCHAR *buf;
buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
if (buf == NULL)
return NULL;
wsprintf(buf, L"%S", str);
return buf;
#else /* UNICODE */
return os_strdup(str);
#endif /* UNICODE */
}
#endif /* CONFIG_NATIVE_WINDOWS */
/**
* wpa_ssid_txt - Convert SSID to a printable string
* @ssid: SSID (32-octet string)
* @ssid_len: Length of ssid in octets
* Returns: Pointer to a printable string
*
* This function can be used to convert SSIDs into printable form. In most
* cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
* does not limit the used character set, so anything could be used in an SSID.
*
* This function uses a static buffer, so only one call can be used at the
* time, i.e., this is not re-entrant and the returned buffer must be used
* before calling this again.
*/
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
{
static char ssid_txt[33];
char *pos;
if (ssid_len > 32)
ssid_len = 32;
os_memcpy(ssid_txt, ssid, ssid_len);
ssid_txt[ssid_len] = '\0';
for (pos = ssid_txt; *pos != '\0'; pos++) {
if ((u8) *pos < 32 || (u8) *pos >= 127)
*pos = '_';
}
return ssid_txt;
}
void * __hide_aliasing_typecast(void *foo)
{
return foo;
}

489
cipher/rsa/common.h Normal file
View File

@ -0,0 +1,489 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef COMMON_H
#define COMMON_H
#include "os.h"
#ifdef __linux__
#include <endian.h>
#include <byteswap.h>
#endif /* __linux__ */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifdef __OpenBSD__
#define bswap_16 swap16
#define bswap_32 swap32
#define bswap_64 swap64
#else /* __OpenBSD__ */
#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64
#endif /* __OpenBSD__ */
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
* defined(__DragonFly__) || defined(__OpenBSD__) */
#ifdef __APPLE__
#include <sys/types.h>
#include <machine/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
static inline unsigned short bswap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static inline unsigned int bswap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#endif /* __APPLE__ */
#ifdef CONFIG_TI_COMPILER
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#ifdef __big_endian__
#define __BYTE_ORDER __BIG_ENDIAN
#else
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
#endif /* CONFIG_TI_COMPILER */
#ifdef __SYMBIAN32__
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* __SYMBIAN32__ */
#ifdef __AIX__
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#ifdef HPUX
#define __BYTE_ORDER __BIG_ENDIAN
static unsigned int bswap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#endif
#ifdef CONFIG_NATIVE_WINDOWS
#include <winsock.h>
typedef int socklen_t;
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0 /* not supported */
#endif
#endif /* CONFIG_NATIVE_WINDOWS */
#ifdef _MSC_VER
#define inline __inline
#undef vsnprintf
#define vsnprintf _vsnprintf
#undef close
#define close closesocket
#endif /* _MSC_VER */
/* Define platform specific integer types */
#ifdef _MSC_VER
typedef UINT64 u64;
typedef UINT32 u32;
typedef UINT16 u16;
typedef UINT8 u8;
typedef INT64 s64;
typedef INT32 s32;
typedef INT16 s16;
typedef INT8 s8;
#define WPA_TYPES_DEFINED
#endif /* _MSC_VER */
#ifdef __vxworks
typedef unsigned long long u64;
typedef UINT32 u32;
typedef UINT16 u16;
typedef UINT8 u8;
typedef long long s64;
typedef INT32 s32;
typedef INT16 s16;
typedef INT8 s8;
#define WPA_TYPES_DEFINED
#endif /* __vxworks */
#ifdef CONFIG_TI_COMPILER
#ifdef _LLONG_AVAILABLE
typedef unsigned long long u64;
#else
/*
* TODO: 64-bit variable not available. Using long as a workaround to test the
* build, but this will likely not work for all operations.
*/
typedef unsigned long u64;
#endif
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define WPA_TYPES_DEFINED
#endif /* CONFIG_TI_COMPILER */
#ifdef __SYMBIAN32__
#define __REMOVE_PLATSEC_DIAGNOSTICS__
#include <e32def.h>
typedef TUint64 u64;
typedef TUint32 u32;
typedef TUint16 u16;
typedef TUint8 u8;
#define WPA_TYPES_DEFINED
#endif /* __SYMBIAN32__ */
#ifndef WPA_TYPES_DEFINED
#ifdef CONFIG_USE_INTTYPES_H
#include <inttypes.h>
#else
#include <stdint.h>
#endif
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
#define WPA_TYPES_DEFINED
#endif /* !WPA_TYPES_DEFINED */
/* Define platform specific byte swapping macros */
#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
static inline unsigned short wpa_swap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static inline unsigned int wpa_swap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) wpa_swap_16(n)
#define host_to_be16(n) wpa_swap_16(n)
#define le_to_host32(n) (n)
#define be_to_host32(n) wpa_swap_32(n)
#define host_to_be32(n) wpa_swap_32(n)
#define WPA_BYTE_SWAP_DEFINED
#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */
#ifndef WPA_BYTE_SWAP_DEFINED
#ifndef __BYTE_ORDER
#ifndef __LITTLE_ENDIAN
#ifndef __BIG_ENDIAN
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#if defined(sparc)
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif /* __BIG_ENDIAN */
#endif /* __LITTLE_ENDIAN */
#endif /* __BYTE_ORDER */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define le_to_host16(n) ((__force u16) (le16) (n))
#define host_to_le16(n) ((__force le16) (u16) (n))
#define be_to_host16(n) bswap_16((__force u16) (be16) (n))
#define host_to_be16(n) ((__force be16) bswap_16((n)))
#define le_to_host32(n) ((__force u32) (le32) (n))
#define host_to_le32(n) ((__force le32) (u32) (n))
#define be_to_host32(n) bswap_32((__force u32) (be32) (n))
#define host_to_be32(n) ((__force be32) bswap_32((n)))
#define le_to_host64(n) ((__force u64) (le64) (n))
#define host_to_le64(n) ((__force le64) (u64) (n))
#define be_to_host64(n) bswap_64((__force u64) (be64) (n))
#define host_to_be64(n) ((__force be64) bswap_64((n)))
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
#define be_to_host16(n) (n)
#define host_to_be16(n) (n)
#define le_to_host32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#define le_to_host64(n) bswap_64(n)
#define host_to_le64(n) bswap_64(n)
#define be_to_host64(n) (n)
#define host_to_be64(n) (n)
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#endif
#else
#error Could not determine CPU byte order
#endif
#define WPA_BYTE_SWAP_DEFINED
#endif /* !WPA_BYTE_SWAP_DEFINED */
/* Macros for handling unaligned memory accesses */
#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
#define WPA_PUT_BE16(a, val) \
do { \
(a)[0] = ((u16) (val)) >> 8; \
(a)[1] = ((u16) (val)) & 0xff; \
} while (0)
#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
#define WPA_PUT_LE16(a, val) \
do { \
(a)[1] = ((u16) (val)) >> 8; \
(a)[0] = ((u16) (val)) & 0xff; \
} while (0)
#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
((u32) (a)[2]))
#define WPA_PUT_BE24(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[2] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
(((u32) (a)[2]) << 8) | ((u32) (a)[3]))
#define WPA_PUT_BE32(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[3] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
(((u32) (a)[1]) << 8) | ((u32) (a)[0]))
#define WPA_PUT_LE32(a, val) \
do { \
(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[0] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
(((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
(((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
(((u64) (a)[6]) << 8) | ((u64) (a)[7]))
#define WPA_PUT_BE64(a, val) \
do { \
(a)[0] = (u8) (((u64) (val)) >> 56); \
(a)[1] = (u8) (((u64) (val)) >> 48); \
(a)[2] = (u8) (((u64) (val)) >> 40); \
(a)[3] = (u8) (((u64) (val)) >> 32); \
(a)[4] = (u8) (((u64) (val)) >> 24); \
(a)[5] = (u8) (((u64) (val)) >> 16); \
(a)[6] = (u8) (((u64) (val)) >> 8); \
(a)[7] = (u8) (((u64) (val)) & 0xff); \
} while (0)
#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
(((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
(((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
(((u64) (a)[1]) << 8) | ((u64) (a)[0]))
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#ifndef ETH_P_ALL
#define ETH_P_ALL 0x0003
#endif
#ifndef ETH_P_PAE
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#endif /* ETH_P_PAE */
#ifndef ETH_P_EAPOL
#define ETH_P_EAPOL ETH_P_PAE
#endif /* ETH_P_EAPOL */
#ifndef ETH_P_RSN_PREAUTH
#define ETH_P_RSN_PREAUTH 0x88c7
#endif /* ETH_P_RSN_PREAUTH */
#ifndef ETH_P_RRB
#define ETH_P_RRB 0x890D
#endif /* ETH_P_RRB */
#ifdef __GNUC__
#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
#define STRUCT_PACKED __attribute__ ((packed))
#else
#define PRINTF_FORMAT(a,b)
#define STRUCT_PACKED
#endif
#ifdef CONFIG_ANSI_C_EXTRA
#if !defined(_MSC_VER) || _MSC_VER < 1400
/* snprintf - used in number of places; sprintf() is _not_ a good replacement
* due to possible buffer overflow; see, e.g.,
* http://www.ijs.si/software/snprintf/ for portable implementation of
* snprintf. */
int snprintf(char *str, size_t size, const char *format, ...);
/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */
/* getopt - only used in main.c */
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind;
#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF
#ifndef __socklen_t_defined
typedef int socklen_t;
#endif
#endif
/* inline - define as __inline or just define it to be empty, if needed */
#ifdef CONFIG_NO_INLINE
#define inline
#else
#define inline __inline
#endif
#ifndef __func__
#define __func__ "__func__ not defined"
#endif
#ifndef bswap_16
#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
#endif
#ifndef bswap_32
#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \
(((u32) (a) << 8) & 0xff0000) | \
(((u32) (a) >> 8) & 0xff00) | \
(((u32) (a) >> 24) & 0xff))
#endif
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0
#endif
#ifdef _WIN32_WCE
void perror(const char *s);
#endif /* _WIN32_WCE */
#endif /* CONFIG_ANSI_C_EXTRA */
#ifndef MAC2STR
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
/*
* Definitions for sparse validation
* (http://kernel.org/pub/linux/kernel/people/josh/sparse/)
*/
#ifdef __CHECKER__
#define __force __attribute__((force))
#define __bitwise __attribute__((bitwise))
#else
#define __force
#define __bitwise
#endif
typedef u16 __bitwise be16;
typedef u16 __bitwise le16;
typedef u32 __bitwise be32;
typedef u32 __bitwise le32;
typedef u64 __bitwise be64;
typedef u64 __bitwise le64;
#ifndef __must_check
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define __must_check __attribute__((__warn_unused_result__))
#else
#define __must_check
#endif /* __GNUC__ */
#endif /* __must_check */
int hwaddr_aton(const char *txt, u8 *addr);
int hexstr2bin(const char *hex, u8 *buf, size_t len);
void inc_byte_array(u8 *counter, size_t len);
void wpa_get_ntp_timestamp(u8 *buf);
int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
size_t len);
#ifdef CONFIG_NATIVE_WINDOWS
void wpa_unicode2ascii_inplace(TCHAR *str);
TCHAR * wpa_strdup_tchar(const char *str);
#else /* CONFIG_NATIVE_WINDOWS */
#define wpa_unicode2ascii_inplace(s) do { } while (0)
#define wpa_strdup_tchar(s) strdup((s))
#endif /* CONFIG_NATIVE_WINDOWS */
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
static inline int is_zero_ether_addr(const u8 *a)
{
return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]);
}
#include "wpa_debug.h"
/*
* gcc 4.4 ends up generating strict-aliasing warnings about some very common
* networking socket uses that do not really result in a real problem and
* cannot be easily avoided with union-based type-punning due to struct
* definitions including another struct in system header files. To avoid having
* to fully disable strict-aliasing warnings, provide a mechanism to hide the
* typecast from aliasing for now. A cleaner solution will hopefully be found
* in the future to handle these cases.
*/
void * __hide_aliasing_typecast(void *foo);
#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a))
#endif /* COMMON_H */

59
cipher/rsa/includes.h Normal file
View File

@ -0,0 +1,59 @@
/*
* wpa_supplicant/hostapd - Default include files
* Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*
* This header file is included into all C files so that commonly used header
* files can be selected with OS specific ifdef blocks in one place instead of
* having to have OS/C library specific selection in many files.
*/
#ifndef INCLUDES_H
#define INCLUDES_H
/* Include possible build time configuration before including anything else */
#include "build_config.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#ifndef _WIN32_WCE
#ifndef CONFIG_TI_COMPILER
#include <signal.h>
#include <sys/types.h>
#endif /* CONFIG_TI_COMPILER */
#include <errno.h>
#endif /* _WIN32_WCE */
#include <ctype.h>
#include <time.h>
#ifndef CONFIG_TI_COMPILER
#ifndef _MSC_VER
#include <unistd.h>
#endif /* _MSC_VER */
#endif /* CONFIG_TI_COMPILER */
#ifndef CONFIG_NATIVE_WINDOWS
#ifndef CONFIG_TI_COMPILER
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef __vxworks
#ifndef __SYMBIAN32__
#include <sys/uio.h>
#endif /* __SYMBIAN32__ */
#include <sys/time.h>
#endif /* __vxworks */
#endif /* CONFIG_TI_COMPILER */
#endif /* CONFIG_NATIVE_WINDOWS */
#endif /* INCLUDES_H */

3381
cipher/rsa/libtommath.c Normal file

File diff suppressed because it is too large Load Diff

512
cipher/rsa/os.h Normal file
View File

@ -0,0 +1,512 @@
/*
* OS specific functions
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef OS_H
#define OS_H
#if defined(HPUX)
#define inline
#endif
typedef long os_time_t;
/**
* os_sleep - Sleep (sec, usec)
* @sec: Number of seconds to sleep
* @usec: Number of microseconds to sleep
*/
void os_sleep(os_time_t sec, os_time_t usec);
struct os_time {
os_time_t sec;
os_time_t usec;
};
/**
* os_get_time - Get current time (sec, usec)
* @t: Pointer to buffer for the time
* Returns: 0 on success, -1 on failure
*/
int os_get_time(struct os_time *t);
/* Helper macros for handling struct os_time */
#define os_time_before(a, b) \
((a)->sec < (b)->sec || \
((a)->sec == (b)->sec && (a)->usec < (b)->usec))
#define os_time_sub(a, b, res) do { \
(res)->sec = (a)->sec - (b)->sec; \
(res)->usec = (a)->usec - (b)->usec; \
if ((res)->usec < 0) { \
(res)->sec--; \
(res)->usec += 1000000; \
} \
} while (0)
/**
* os_mktime - Convert broken-down time into seconds since 1970-01-01
* @year: Four digit year
* @month: Month (1 .. 12)
* @day: Day of month (1 .. 31)
* @hour: Hour (0 .. 23)
* @min: Minute (0 .. 59)
* @sec: Second (0 .. 60)
* @t: Buffer for returning calendar time representation (seconds since
* 1970-01-01 00:00:00)
* Returns: 0 on success, -1 on failure
*
* Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
* which is used by POSIX mktime().
*/
int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t);
/**
* os_daemonize - Run in the background (detach from the controlling terminal)
* @pid_file: File name to write the process ID to or %NULL to skip this
* Returns: 0 on success, -1 on failure
*/
int os_daemonize(const char *pid_file);
/**
* os_daemonize_terminate - Stop running in the background (remove pid file)
* @pid_file: File name to write the process ID to or %NULL to skip this
*/
void os_daemonize_terminate(const char *pid_file);
/**
* os_get_random - Get cryptographically strong pseudo random data
* @buf: Buffer for pseudo random data
* @len: Length of the buffer
* Returns: 0 on success, -1 on failure
*/
int os_get_random(unsigned char *buf, size_t len);
/**
* os_random - Get pseudo random value (not necessarily very strong)
* Returns: Pseudo random value
*/
unsigned long os_random(void);
/**
* os_rel2abs_path - Get an absolute path for a file
* @rel_path: Relative path to a file
* Returns: Absolute path for the file or %NULL on failure
*
* This function tries to convert a relative path of a file to an absolute path
* in order for the file to be found even if current working directory has
* changed. The returned value is allocated and caller is responsible for
* freeing it. It is acceptable to just return the same path in an allocated
* buffer, e.g., return strdup(rel_path). This function is only used to find
* configuration files when os_daemonize() may have changed the current working
* directory and relative path would be pointing to a different location.
*/
char * os_rel2abs_path(const char *rel_path);
/**
* os_program_init - Program initialization (called at start)
* Returns: 0 on success, -1 on failure
*
* This function is called when a programs starts. If there are any OS specific
* processing that is needed, it can be placed here. It is also acceptable to
* just return 0 if not special processing is needed.
*/
int os_program_init(void);
/**
* os_program_deinit - Program deinitialization (called just before exit)
*
* This function is called just before a program exists. If there are any OS
* specific processing, e.g., freeing resourced allocated in os_program_init(),
* it should be done here. It is also acceptable for this function to do
* nothing.
*/
void os_program_deinit(void);
/**
* os_setenv - Set environment variable
* @name: Name of the variable
* @value: Value to set to the variable
* @overwrite: Whether existing variable should be overwritten
* Returns: 0 on success, -1 on error
*
* This function is only used for wpa_cli action scripts. OS wrapper does not
* need to implement this if such functionality is not needed.
*/
int os_setenv(const char *name, const char *value, int overwrite);
/**
* os_unsetenv - Delete environent variable
* @name: Name of the variable
* Returns: 0 on success, -1 on error
*
* This function is only used for wpa_cli action scripts. OS wrapper does not
* need to implement this if such functionality is not needed.
*/
int os_unsetenv(const char *name);
/**
* os_readfile - Read a file to an allocated memory buffer
* @name: Name of the file to read
* @len: For returning the length of the allocated buffer
* Returns: Pointer to the allocated buffer or %NULL on failure
*
* This function allocates memory and reads the given file to this buffer. Both
* binary and text files can be read with this function. The caller is
* responsible for freeing the returned buffer with os_free().
*/
char * os_readfile(const char *name, size_t *len);
/**
* os_zalloc - Allocate and zero memory
* @size: Number of bytes to allocate
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
void * os_zalloc(size_t size);
/*
* The following functions are wrapper for standard ANSI C or POSIX functions.
* By default, they are just defined to use the standard function name and no
* os_*.c implementation is needed for them. This avoids extra function calls
* by allowing the C pre-processor take care of the function name mapping.
*
* If the target system uses a C library that does not provide these functions,
* build_config.h can be used to define the wrappers to use a different
* function name. This can be done on function-by-function basis since the
* defines here are only used if build_config.h does not define the os_* name.
* If needed, os_*.c file can be used to implement the functions that are not
* included in the C library on the target system. Alternatively,
* OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case
* these functions need to be implemented in os_*.c file for the target system.
*/
#ifdef OS_NO_C_LIB_DEFINES
/**
* os_malloc - Allocate dynamic memory
* @size: Size of the buffer to allocate
* Returns: Allocated buffer or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
void * os_malloc(size_t size);
/**
* os_realloc - Re-allocate dynamic memory
* @ptr: Old buffer from os_malloc() or os_realloc()
* @size: Size of the new buffer
* Returns: Allocated buffer or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
* If re-allocation fails, %NULL is returned and the original buffer (ptr) is
* not freed and caller is still responsible for freeing it.
*/
void * os_realloc(void *ptr, size_t size);
/**
* os_free - Free dynamic memory
* @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL
*/
void os_free(void *ptr);
/**
* os_memcpy - Copy memory area
* @dest: Destination
* @src: Source
* @n: Number of bytes to copy
* Returns: dest
*
* The memory areas src and dst must not overlap. os_memmove() can be used with
* overlapping memory.
*/
void * os_memcpy(void *dest, const void *src, size_t n);
/**
* os_memmove - Copy memory area
* @dest: Destination
* @src: Source
* @n: Number of bytes to copy
* Returns: dest
*
* The memory areas src and dst may overlap.
*/
void * os_memmove(void *dest, const void *src, size_t n);
/**
* os_memset - Fill memory with a constant byte
* @s: Memory area to be filled
* @c: Constant byte
* @n: Number of bytes started from s to fill with c
* Returns: s
*/
void * os_memset(void *s, int c, size_t n);
/**
* os_memcmp - Compare memory areas
* @s1: First buffer
* @s2: Second buffer
* @n: Maximum numbers of octets to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_memcmp(const void *s1, const void *s2, size_t n);
/**
* os_strdup - Duplicate a string
* @s: Source string
* Returns: Allocated buffer with the string copied into it or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
char * os_strdup(const char *s);
/**
* os_strlen - Calculate the length of a string
* @s: '\0' terminated string
* Returns: Number of characters in s (not counting the '\0' terminator)
*/
size_t os_strlen(const char *s);
/**
* os_strcasecmp - Compare two strings ignoring case
* @s1: First string
* @s2: Second string
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greatred than s2
*/
int os_strcasecmp(const char *s1, const char *s2);
/**
* os_strncasecmp - Compare two strings ignoring case
* @s1: First string
* @s2: Second string
* @n: Maximum numbers of characters to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_strncasecmp(const char *s1, const char *s2, size_t n);
/**
* os_strchr - Locate the first occurrence of a character in string
* @s: String
* @c: Character to search for
* Returns: Pointer to the matched character or %NULL if not found
*/
char * os_strchr(const char *s, int c);
/**
* os_strrchr - Locate the last occurrence of a character in string
* @s: String
* @c: Character to search for
* Returns: Pointer to the matched character or %NULL if not found
*/
char * os_strrchr(const char *s, int c);
/**
* os_strcmp - Compare two strings
* @s1: First string
* @s2: Second string
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greatred than s2
*/
int os_strcmp(const char *s1, const char *s2);
/**
* os_strncmp - Compare two strings
* @s1: First string
* @s2: Second string
* @n: Maximum numbers of characters to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_strncmp(const char *s1, const char *s2, size_t n);
/**
* os_strncpy - Copy a string
* @dest: Destination
* @src: Source
* @n: Maximum number of characters to copy
* Returns: dest
*/
char * os_strncpy(char *dest, const char *src, size_t n);
/**
* os_strstr - Locate a substring
* @haystack: String (haystack) to search from
* @needle: Needle to search from haystack
* Returns: Pointer to the beginning of the substring or %NULL if not found
*/
char * os_strstr(const char *haystack, const char *needle);
/**
* os_snprintf - Print to a memory buffer
* @str: Memory buffer to print into
* @size: Maximum length of the str buffer
* @format: printf format
* Returns: Number of characters printed (not including trailing '\0').
*
* If the output buffer is truncated, number of characters which would have
* been written is returned. Since some C libraries return -1 in such a case,
* the caller must be prepared on that value, too, to indicate truncation.
*
* Note: Some C library implementations of snprintf() may not guarantee null
* termination in case the output is truncated. The OS wrapper function of
* os_snprintf() should provide this guarantee, i.e., to null terminate the
* output buffer if a C library version of the function is used and if that
* function does not guarantee null termination.
*
* If the target system does not include snprintf(), see, e.g.,
* http://www.ijs.si/software/snprintf/ for an example of a portable
* implementation of snprintf.
*/
int os_snprintf(char *str, size_t size, const char *format, ...);
#else /* OS_NO_C_LIB_DEFINES */
#ifdef WPA_TRACE
void * os_malloc(size_t size);
void * os_realloc(void *ptr, size_t size);
void os_free(void *ptr);
char * os_strdup(const char *s);
#else /* WPA_TRACE */
#ifndef os_malloc
#define os_malloc(s) malloc((s))
#endif
#ifndef os_realloc
#define os_realloc(p, s) realloc((p), (s))
#endif
#ifndef os_free
#define os_free(p) free((p))
#endif
#ifndef os_strdup
#ifdef _MSC_VER
#define os_strdup(s) _strdup(s)
#else
#define os_strdup(s) strdup(s)
#endif
#endif
#endif /* WPA_TRACE */
#ifndef os_memcpy
#define os_memcpy(d, s, n) memcpy((d), (s), (n))
#endif
#ifndef os_memmove
#define os_memmove(d, s, n) memmove((d), (s), (n))
#endif
#ifndef os_memset
#define os_memset(s, c, n) memset(s, c, n)
#endif
#ifndef os_memcmp
#define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n))
#endif
#ifndef os_strlen
#define os_strlen(s) strlen(s)
#endif
#ifndef os_strcasecmp
#ifdef _MSC_VER
#define os_strcasecmp(s1, s2) _stricmp((s1), (s2))
#else
#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2))
#endif
#endif
#ifndef os_strncasecmp
#ifdef _MSC_VER
#define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n))
#else
#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
#endif
#endif
#ifndef os_strchr
#define os_strchr(s, c) strchr((s), (c))
#endif
#ifndef os_strcmp
#define os_strcmp(s1, s2) strcmp((s1), (s2))
#endif
#ifndef os_strncmp
#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
#endif
#ifndef os_strncpy
#define os_strncpy(d, s, n) strncpy((d), (s), (n))
#endif
#ifndef os_strrchr
#define os_strrchr(s, c) strrchr((s), (c))
#endif
#ifndef os_strstr
#define os_strstr(h, n) strstr((h), (n))
#endif
#ifndef os_snprintf
#ifdef _MSC_VER
#define os_snprintf _snprintf
#else
#define os_snprintf snprintf
#endif
#endif
#endif /* OS_NO_C_LIB_DEFINES */
/**
* os_strlcpy - Copy a string with size bound and NUL-termination
* @dest: Destination
* @src: Source
* @siz: Size of the target buffer
* Returns: Total length of the target string (length of src) (not including
* NUL-termination)
*
* This function matches in behavior with the strlcpy(3) function in OpenBSD.
*/
size_t os_strlcpy(char *dest, const char *src, size_t siz);
#ifdef OS_REJECT_C_LIB_FUNCTIONS
#define malloc OS_DO_NOT_USE_malloc
#define realloc OS_DO_NOT_USE_realloc
#define free OS_DO_NOT_USE_free
#define memcpy OS_DO_NOT_USE_memcpy
#define memmove OS_DO_NOT_USE_memmove
#define memset OS_DO_NOT_USE_memset
#define memcmp OS_DO_NOT_USE_memcmp
#undef strdup
#define strdup OS_DO_NOT_USE_strdup
#define strlen OS_DO_NOT_USE_strlen
#define strcasecmp OS_DO_NOT_USE_strcasecmp
#define strncasecmp OS_DO_NOT_USE_strncasecmp
#undef strchr
#define strchr OS_DO_NOT_USE_strchr
#undef strcmp
#define strcmp OS_DO_NOT_USE_strcmp
#undef strncmp
#define strncmp OS_DO_NOT_USE_strncmp
#undef strncpy
#define strncpy OS_DO_NOT_USE_strncpy
#define strrchr OS_DO_NOT_USE_strrchr
#define strstr OS_DO_NOT_USE_strstr
#undef snprintf
#define snprintf OS_DO_NOT_USE_snprintf
#define strcpy OS_DO_NOT_USE_strcpy
#endif /* OS_REJECT_C_LIB_FUNCTIONS */
#endif /* OS_H */

439
cipher/rsa/os_unix.c Normal file
View File

@ -0,0 +1,439 @@
/*
* OS specific functions for UNIX/POSIX systems
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "os.h"
#ifdef WPA_TRACE
#include "common.h"
#include "list.h"
#include "wpa_debug.h"
#include "trace.h"
static struct dl_list alloc_list;
#define ALLOC_MAGIC 0xa84ef1b2
#define FREED_MAGIC 0x67fd487a
struct os_alloc_trace {
unsigned int magic;
struct dl_list list;
size_t len;
WPA_TRACE_INFO
};
#endif /* WPA_TRACE */
void os_sleep(os_time_t sec, os_time_t usec)
{
if (sec)
sleep(sec);
if (usec)
usleep(usec);
}
int os_get_time(struct os_time *t)
{
int res;
struct timeval tv;
res = gettimeofday(&tv, NULL);
t->sec = tv.tv_sec;
t->usec = tv.tv_usec;
return res;
}
int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t)
{
struct tm tm, *tm1;
time_t t_local, t1, t2;
os_time_t tz_offset;
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
sec > 60)
return -1;
memset(&tm, 0, sizeof(tm));
tm.tm_year = year - 1900;
tm.tm_mon = month - 1;
tm.tm_mday = day;
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec;
t_local = mktime(&tm);
/* figure out offset to UTC */
tm1 = localtime(&t_local);
if (tm1) {
t1 = mktime(tm1);
tm1 = gmtime(&t_local);
if (tm1) {
t2 = mktime(tm1);
tz_offset = t2 - t1;
} else
tz_offset = 0;
} else
tz_offset = 0;
*t = (os_time_t) t_local - tz_offset;
return 0;
}
#ifdef __APPLE__
#include <fcntl.h>
static int os_daemon(int nochdir, int noclose)
{
int devnull;
if (chdir("/") < 0)
return -1;
devnull = open("/dev/null", O_RDWR);
if (devnull < 0)
return -1;
if (dup2(devnull, STDIN_FILENO) < 0) {
close(devnull);
return -1;
}
if (dup2(devnull, STDOUT_FILENO) < 0) {
close(devnull);
return -1;
}
if (dup2(devnull, STDERR_FILENO) < 0) {
close(devnull);
return -1;
}
return 0;
}
#else /* __APPLE__ */
#define os_daemon daemon
#endif /* __APPLE__ */
int os_daemonize(const char *pid_file)
{
#ifdef __uClinux__
return -1;
#else /* __uClinux__ */
/* if (os_daemon(0, 0)) {
perror("daemon");
return -1;
}
if (pid_file) {
FILE *f = fopen(pid_file, "w");
if (f) {
fprintf(f, "%u\n", getpid());
fclose(f);
}
}
*/
return -0;
#endif /* __uClinux__ */
}
void os_daemonize_terminate(const char *pid_file)
{
if (pid_file)
unlink(pid_file);
}
int os_get_random(unsigned char *buf, size_t len)
{
FILE *f;
size_t rc;
f = fopen("/dev/urandom", "rb");
if (f == NULL) {
printf("Could not open /dev/urandom.\n");
return -1;
}
rc = fread(buf, 1, len, f);
fclose(f);
return rc != len ? -1 : 0;
}
unsigned long os_random(void)
{
return random();
}
char * os_rel2abs_path(const char *rel_path)
{
char *buf = NULL, *cwd, *ret;
size_t len = 128, cwd_len, rel_len, ret_len;
int last_errno;
if (rel_path[0] == '/')
return os_strdup(rel_path);
for (;;) {
buf = os_malloc(len);
if (buf == NULL)
return NULL;
cwd = getcwd(buf, len);
if (cwd == NULL) {
last_errno = errno;
os_free(buf);
if (last_errno != ERANGE)
return NULL;
len *= 2;
if (len > 2000)
return NULL;
} else {
buf[len - 1] = '\0';
break;
}
}
cwd_len = os_strlen(cwd);
rel_len = os_strlen(rel_path);
ret_len = cwd_len + 1 + rel_len + 1;
ret = os_malloc(ret_len);
if (ret) {
os_memcpy(ret, cwd, cwd_len);
ret[cwd_len] = '/';
os_memcpy(ret + cwd_len + 1, rel_path, rel_len);
ret[ret_len - 1] = '\0';
}
os_free(buf);
return ret;
}
int os_program_init(void)
{
#ifdef WPA_TRACE
dl_list_init(&alloc_list);
#endif /* WPA_TRACE */
return 0;
}
void os_program_deinit(void)
{
#ifdef WPA_TRACE
struct os_alloc_trace *a;
unsigned long total = 0;
dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) {
total += a->len;
if (a->magic != ALLOC_MAGIC) {
wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x "
"len %lu",
a, a->magic, (unsigned long) a->len);
continue;
}
wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu",
a, (unsigned long) a->len);
wpa_trace_dump("memleak", a);
}
if (total)
wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes",
(unsigned long) total);
#endif /* WPA_TRACE */
}
int os_setenv(const char *name, const char *value, int overwrite)
{
//return setenv(name, value, overwrite);
return -1;
}
int os_unsetenv(const char *name)
{
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
defined(__OpenBSD__)
unsetenv(name);
return 0;
#else
//return unsetenv(name);
return -1;
#endif
}
char * os_readfile(const char *name, size_t *len)
{
FILE *f;
char *buf;
f = fopen(name, "rb");
if (f == NULL)
return NULL;
fseek(f, 0, SEEK_END);
*len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = os_malloc(*len);
if (buf == NULL) {
fclose(f);
return NULL;
}
if (fread(buf, 1, *len, f) != *len) {
fclose(f);
os_free(buf);
return NULL;
}
fclose(f);
return buf;
}
#ifndef WPA_TRACE
void * os_zalloc(size_t size)
{
return calloc(1, size);
}
#endif /* WPA_TRACE */
size_t os_strlcpy(char *dest, const char *src, size_t siz)
{
const char *s = src;
size_t left = siz;
if (left) {
/* Copy string up to the maximum size of the dest buffer */
while (--left != 0) {
if ((*dest++ = *s++) == '\0')
break;
}
}
if (left == 0) {
/* Not enough room for the string; force NUL-termination */
if (siz != 0)
*dest = '\0';
while (*s++)
; /* determine total src string length */
}
return s - src - 1;
}
#ifdef WPA_TRACE
void * os_malloc(size_t size)
{
struct os_alloc_trace *a;
a = malloc(sizeof(*a) + size);
if (a == NULL)
return NULL;
a->magic = ALLOC_MAGIC;
dl_list_add(&alloc_list, &a->list);
a->len = size;
wpa_trace_record(a);
return a + 1;
}
void * os_realloc(void *ptr, size_t size)
{
struct os_alloc_trace *a;
size_t copy_len;
void *n;
if (ptr == NULL)
return os_malloc(size);
a = ptr - sizeof(*a);
if (a->magic != ALLOC_MAGIC) {
wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s",
a, a->magic,
a->magic == FREED_MAGIC ? " (already freed)" : "");
wpa_trace_show("Invalid os_realloc() call");
abort();
}
n = os_malloc(size);
if (n == NULL)
return NULL;
copy_len = a->len;
if (copy_len > size)
copy_len = size;
os_memcpy(n, a + 1, copy_len);
os_free(ptr);
return n;
}
void os_free(void *ptr)
{
struct os_alloc_trace *a;
if (ptr == NULL)
return;
a = ptr - sizeof(*a);
if (a->magic != ALLOC_MAGIC) {
wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s",
a, a->magic,
a->magic == FREED_MAGIC ? " (already freed)" : "");
wpa_trace_show("Invalid os_free() call");
abort();
}
dl_list_del(&a->list);
a->magic = FREED_MAGIC;
wpa_trace_check_ref(ptr);
free(a);
}
void * os_zalloc(size_t size)
{
void *ptr = os_malloc(size);
if (ptr)
os_memset(ptr, 0, size);
return ptr;
}
char * os_strdup(const char *s)
{
size_t len;
char *d;
len = os_strlen(s);
d = os_malloc(len + 1);
if (d == NULL)
return NULL;
os_memcpy(d, s, len);
d[len] = '\0';
return d;
}
#endif /* WPA_TRACE */

374
cipher/rsa/rsa.c Normal file
View File

@ -0,0 +1,374 @@
/*
* RSA
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "asn1.h"
#include "bignum.h"
#include "rsa.h"
struct crypto_rsa_key {
int private_key; /* whether private key is set */
struct bignum *n; /* modulus (p * q) */
struct bignum *e; /* public exponent */
/* The following parameters are available only if private_key is set */
struct bignum *d; /* private exponent */
struct bignum *p; /* prime p (factor of n) */
struct bignum *q; /* prime q (factor of n) */
struct bignum *dmp1; /* d mod (p - 1); CRT exponent */
struct bignum *dmq1; /* d mod (q - 1); CRT exponent */
struct bignum *iqmp; /* 1 / q mod p; CRT coefficient */
};
static const u8 * crypto_rsa_parse_integer(const u8 *pos, const u8 *end,
struct bignum *num)
{
struct asn1_hdr hdr;
if (pos == NULL)
return NULL;
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
wpa_printf(MSG_DEBUG, "RSA: Expected INTEGER - found class %d "
"tag 0x%x", hdr.class, hdr.tag);
return NULL;
}
if (bignum_set_unsigned_bin(num, hdr.payload, hdr.length) < 0) {
wpa_printf(MSG_DEBUG, "RSA: Failed to parse INTEGER");
return NULL;
}
return hdr.payload + hdr.length;
}
/**
* crypto_rsa_import_public_key - Import an RSA public key
* @buf: Key buffer (DER encoded RSA public key)
* @len: Key buffer length in bytes
* Returns: Pointer to the public key or %NULL on failure
*/
struct crypto_rsa_key *
crypto_rsa_import_public_key(const u8 *buf, size_t len)
{
struct crypto_rsa_key *key;
struct asn1_hdr hdr;
const u8 *pos, *end;
key = os_zalloc(sizeof(*key));
if (key == NULL)
return NULL;
key->n = bignum_init();
key->e = bignum_init();
if (key->n == NULL || key->e == NULL) {
crypto_rsa_free(key);
return NULL;
}
/*
* PKCS #1, 7.1:
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
if (asn1_get_next(buf, len, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL ||
hdr.tag != ASN1_TAG_SEQUENCE) {
wpa_printf(MSG_DEBUG, "RSA: Expected SEQUENCE "
"(public key) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto error;
}
pos = hdr.payload;
end = pos + hdr.length;
/***/
//printf("len=%d\n", hdr.length);
asn1_get_next(pos, end-pos, &hdr);
//printf("tag 0x%x, len=%d\n", hdr.tag, hdr.length);
pos = hdr.payload + hdr.length;
asn1_get_next(pos, end-pos, &hdr);
//printf("tag 0x%x, len=%d\n", hdr.tag, hdr.length);
pos = hdr.payload + 1; //why 00 ahead?
asn1_get_next(pos, end-pos, &hdr);
//printf("tag 0x%x, len=%d\n", hdr.tag, hdr.length);
pos = hdr.payload;
/***/
pos = crypto_rsa_parse_integer(pos, end, key->n);
pos = crypto_rsa_parse_integer(pos, end, key->e);
if (pos == NULL)
goto error;
if (pos != end) {
wpa_hexdump(MSG_DEBUG,
"RSA: Extra data in public key SEQUENCE",
pos, end - pos);
goto error;
}
return key;
error:
crypto_rsa_free(key);
return NULL;
}
/**
* crypto_rsa_import_private_key - Import an RSA private key
* @buf: Key buffer (DER encoded RSA private key)
* @len: Key buffer length in bytes
* Returns: Pointer to the private key or %NULL on failure
*/
struct crypto_rsa_key *
crypto_rsa_import_private_key(const u8 *buf, size_t len)
{
struct crypto_rsa_key *key;
struct bignum *zero;
struct asn1_hdr hdr;
const u8 *pos, *end;
key = os_zalloc(sizeof(*key));
if (key == NULL)
return NULL;
key->private_key = 1;
key->n = bignum_init();
key->e = bignum_init();
key->d = bignum_init();
key->p = bignum_init();
key->q = bignum_init();
key->dmp1 = bignum_init();
key->dmq1 = bignum_init();
key->iqmp = bignum_init();
if (key->n == NULL || key->e == NULL || key->d == NULL ||
key->p == NULL || key->q == NULL || key->dmp1 == NULL ||
key->dmq1 == NULL || key->iqmp == NULL) {
crypto_rsa_free(key);
return NULL;
}
/*
* PKCS #1, 7.2:
* RSAPrivateKey ::= SEQUENCE {
* version Version,
* modulus INTEGER, -- n
* publicExponent INTEGER, -- e
* privateExponent INTEGER, -- d
* prime1 INTEGER, -- p
* prime2 INTEGER, -- q
* exponent1 INTEGER, -- d mod (p-1)
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER -- (inverse of q) mod p
* }
*
* Version ::= INTEGER -- shall be 0 for this version of the standard
*/
if (asn1_get_next(buf, len, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL ||
hdr.tag != ASN1_TAG_SEQUENCE) {
wpa_printf(MSG_DEBUG, "RSA: Expected SEQUENCE "
"(public key) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto error;
}
pos = hdr.payload;
end = pos + hdr.length;
zero = bignum_init();
if (zero == NULL)
goto error;
pos = crypto_rsa_parse_integer(pos, end, zero);
if (pos == NULL || bignum_cmp_d(zero, 0) != 0) {
wpa_printf(MSG_DEBUG, "RSA: Expected zero INTEGER in the "
"beginning of private key; not found");
bignum_deinit(zero);
goto error;
}
bignum_deinit(zero);
pos = crypto_rsa_parse_integer(pos, end, key->n);
pos = crypto_rsa_parse_integer(pos, end, key->e);
pos = crypto_rsa_parse_integer(pos, end, key->d);
pos = crypto_rsa_parse_integer(pos, end, key->p);
pos = crypto_rsa_parse_integer(pos, end, key->q);
pos = crypto_rsa_parse_integer(pos, end, key->dmp1);
pos = crypto_rsa_parse_integer(pos, end, key->dmq1);
pos = crypto_rsa_parse_integer(pos, end, key->iqmp);
if (pos == NULL)
goto error;
if (pos != end) {
wpa_hexdump(MSG_DEBUG,
"RSA: Extra data in public key SEQUENCE",
pos, end - pos);
goto error;
}
return key;
error:
crypto_rsa_free(key);
return NULL;
}
/**
* crypto_rsa_get_modulus_len - Get the modulus length of the RSA key
* @key: RSA key
* Returns: Modulus length of the key
*/
size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key *key)
{
return bignum_get_unsigned_bin_len(key->n);
}
/**
* crypto_rsa_exptmod - RSA modular exponentiation
* @in: Input data
* @inlen: Input data length
* @out: Buffer for output data
* @outlen: Maximum size of the output buffer and used size on success
* @key: RSA key
* @use_private: 1 = Use RSA private key, 0 = Use RSA public key
* Returns: 0 on success, -1 on failure
*/
int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen,
struct crypto_rsa_key *key, int use_private)
{
struct bignum *tmp, *a = NULL, *b = NULL;
int ret = -1;
size_t modlen;
if (use_private && !key->private_key)
return -1;
tmp = bignum_init();
if (tmp == NULL)
return -1;
if (bignum_set_unsigned_bin(tmp, in, inlen) < 0)
goto error;
if (bignum_cmp(key->n, tmp) < 0) {
/* Too large input value for the RSA key modulus */
goto error;
}
if (use_private) {
/*
* Decrypt (or sign) using Chinese remainer theorem to speed
* up calculation. This is equivalent to tmp = tmp^d mod n
* (which would require more CPU to calculate directly).
*
* dmp1 = (1/e) mod (p-1)
* dmq1 = (1/e) mod (q-1)
* iqmp = (1/q) mod p, where p > q
* m1 = c^dmp1 mod p
* m2 = c^dmq1 mod q
* h = q^-1 (m1 - m2) mod p
* m = m2 + hq
*/
a = bignum_init();
b = bignum_init();
if (a == NULL || b == NULL)
goto error;
/* a = tmp^dmp1 mod p */
if (bignum_exptmod(tmp, key->dmp1, key->p, a) < 0)
goto error;
/* b = tmp^dmq1 mod q */
if (bignum_exptmod(tmp, key->dmq1, key->q, b) < 0)
goto error;
/* tmp = (a - b) * (1/q mod p) (mod p) */
if (bignum_sub(a, b, tmp) < 0 ||
bignum_mulmod(tmp, key->iqmp, key->p, tmp) < 0)
goto error;
/* tmp = b + q * tmp */
if (bignum_mul(tmp, key->q, tmp) < 0 ||
bignum_add(tmp, b, tmp) < 0)
goto error;
} else {
/* Encrypt (or verify signature) */
/* tmp = tmp^e mod N */
if (bignum_exptmod(tmp, key->e, key->n, tmp) < 0)
goto error;
}
modlen = crypto_rsa_get_modulus_len(key);
if (modlen > *outlen) {
*outlen = modlen;
goto error;
}
if (bignum_get_unsigned_bin_len(tmp) > modlen)
goto error; /* should never happen */
*outlen = modlen;
os_memset(out, 0, modlen);
if (bignum_get_unsigned_bin(
tmp, out +
(modlen - bignum_get_unsigned_bin_len(tmp)), NULL) < 0)
goto error;
ret = 0;
error:
bignum_deinit(tmp);
bignum_deinit(a);
bignum_deinit(b);
return ret;
}
/**
* crypto_rsa_free - Free RSA key
* @key: RSA key to be freed
*
* This function frees an RSA key imported with either
* crypto_rsa_import_public_key() or crypto_rsa_import_private_key().
*/
void crypto_rsa_free(struct crypto_rsa_key *key)
{
if (key) {
bignum_deinit(key->n);
bignum_deinit(key->e);
bignum_deinit(key->d);
bignum_deinit(key->p);
bignum_deinit(key->q);
bignum_deinit(key->dmp1);
bignum_deinit(key->dmq1);
bignum_deinit(key->iqmp);
os_free(key);
}
}

29
cipher/rsa/rsa.h Normal file
View File

@ -0,0 +1,29 @@
/*
* RSA
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef RSA_H
#define RSA_H
struct crypto_rsa_key;
struct crypto_rsa_key *
crypto_rsa_import_public_key(const u8 *buf, size_t len);
struct crypto_rsa_key *
crypto_rsa_import_private_key(const u8 *buf, size_t len);
size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key *key);
int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen,
struct crypto_rsa_key *key, int use_private);
void crypto_rsa_free(struct crypto_rsa_key *key);
#endif /* RSA_H */

139
cipher/rsa/test_rsa.c Normal file
View File

@ -0,0 +1,139 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "common.h"
#include "base64.h"
#include "rsa.h"
static const u8 * search_tag(const char *tag, const u8 *buf, size_t len)
{
size_t i, plen;
plen = os_strlen(tag);
if (len < plen)
return NULL;
for (i = 0; i < len - plen; i++) {
if (os_memcmp(buf + i, tag, plen) == 0)
return buf + i;
}
return NULL;
}
u8* get_key(const char *file, const char *start_tag, const char *end_tag, size_t *outlen)
{
size_t len;
u8 *buf = os_readfile(file, &len);
if (!buf)
return NULL;
const u8 *pos;
const u8 *end;
u8* der;
pos = search_tag(start_tag, buf, len);
if (!pos)
goto err;
pos += strlen(start_tag);
end = search_tag(end_tag, pos, buf + len - pos);
if (!end)
goto err;
der = base64_decode(pos, end-pos, outlen);
//prt(der, *outlen);
free(buf);
return der;
err:
if (buf)
free(buf);
return NULL;
}
static void prt(void *p, int len)
{
int i;
char *d = (char *)p;
for (i = 0; i < len; ++i) {
printf("%02x ", (unsigned char)d[i]);
if (i != 0 && (i+1)%20 == 0)
printf("\n");
}
printf("\n");
}
int main(int argc, char *argv[])
{
extern int wpa_debug_level;
wpa_debug_level = MSG_MSGDUMP;
struct crypto_rsa_key *key = NULL;
u8* buf = NULL;;
size_t l = 0;
if (argc > 1) {
buf = get_key("./pubkey", "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----", &l);
if (!buf)
return 0;
key = crypto_rsa_import_public_key(buf, l);
if (!key) {
printf("private error\n");
goto err;
}
char src[1024];
memset(src, 0, sizeof(src));
strcpy(src, argv[1]);
int mod_len = crypto_rsa_get_modulus_len(key);
printf("modulus len=%d\n", mod_len);
char encrypt_buf[1024];
memset(encrypt_buf, 0, sizeof(encrypt_buf));
size_t buf_len = sizeof(encrypt_buf);
if (0 == crypto_rsa_exptmod(src, mod_len, encrypt_buf, &buf_len, key, 0)) {
printf("result len=%d\n", buf_len);
prt(encrypt_buf, buf_len);
FILE *fp=fopen("out.bin", "w");
if (fp) {
fwrite(encrypt_buf, 1, buf_len, fp);
}
fclose(fp);
}
} else {
buf = get_key("./privkey", "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----", &l);
if (!buf)
return 0;
key = crypto_rsa_import_private_key(buf, l);
if (!key) {
printf("public error\n");
goto err;
}
size_t f_len;
char *p = os_readfile("out.bin", &f_len);
if (p) {
char decrypt_buf[1024];
memset(decrypt_buf, 0, sizeof(decrypt_buf));
size_t buf_len = sizeof(decrypt_buf);
if (0 == crypto_rsa_exptmod(p, f_len, decrypt_buf, &buf_len, key, 1)) {
printf("outlen = %d\n", buf_len);
prt(decrypt_buf, buf_len);
}
free(p);
}
}
err:
free(buf);
crypto_rsa_free(key);
}

329
cipher/rsa/trace.c Normal file
View File

@ -0,0 +1,329 @@
/*
* Backtrace debugging
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "trace.h"
#ifdef WPA_TRACE
static struct dl_list active_references =
{ &active_references, &active_references };
#ifdef WPA_TRACE_BFD
#include <bfd.h>
#ifdef __linux__
#include <demangle.h>
#else /* __linux__ */
#include <libiberty/demangle.h>
#endif /* __linux__ */
static char *prg_fname = NULL;
static bfd *cached_abfd = NULL;
static asymbol **syms = NULL;
static void get_prg_fname(void)
{
char exe[50], fname[512];
int len;
os_snprintf(exe, sizeof(exe) - 1, "/proc/%u/exe", getpid());
len = readlink(exe, fname, sizeof(fname) - 1);
if (len < 0 || len >= (int) sizeof(fname)) {
perror("readlink");
return;
}
fname[len] = '\0';
prg_fname = strdup(fname);
}
static bfd * open_bfd(const char *fname)
{
bfd *abfd;
char **matching;
abfd = bfd_openr(prg_fname, NULL);
if (abfd == NULL) {
wpa_printf(MSG_INFO, "bfd_openr failed");
return NULL;
}
if (bfd_check_format(abfd, bfd_archive)) {
wpa_printf(MSG_INFO, "bfd_check_format failed");
bfd_close(abfd);
return NULL;
}
if (!bfd_check_format_matches(abfd, bfd_object, &matching)) {
wpa_printf(MSG_INFO, "bfd_check_format_matches failed");
free(matching);
bfd_close(abfd);
return NULL;
}
return abfd;
}
static void read_syms(bfd *abfd)
{
long storage, symcount;
bfd_boolean dynamic = FALSE;
if (syms)
return;
if (!(bfd_get_file_flags(abfd) & HAS_SYMS)) {
wpa_printf(MSG_INFO, "No symbols");
return;
}
storage = bfd_get_symtab_upper_bound(abfd);
if (storage == 0) {
storage = bfd_get_dynamic_symtab_upper_bound(abfd);
dynamic = TRUE;
}
if (storage < 0) {
wpa_printf(MSG_INFO, "Unknown symtab upper bound");
return;
}
syms = malloc(storage);
if (syms == NULL) {
wpa_printf(MSG_INFO, "Failed to allocate memory for symtab "
"(%ld bytes)", storage);
return;
}
if (dynamic)
symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
else
symcount = bfd_canonicalize_symtab(abfd, syms);
if (symcount < 0) {
wpa_printf(MSG_INFO, "Failed to canonicalize %ssymtab",
dynamic ? "dynamic " : "");
free(syms);
syms = NULL;
return;
}
}
struct bfd_data {
bfd_vma pc;
bfd_boolean found;
const char *filename;
const char *function;
unsigned int line;
};
static void find_addr_sect(bfd *abfd, asection *section, void *obj)
{
struct bfd_data *data = obj;
bfd_vma vma;
bfd_size_type size;
if (data->found)
return;
if (!(bfd_get_section_vma(abfd, section)))
return;
vma = bfd_get_section_vma(abfd, section);
if (data->pc < vma)
return;
size = bfd_get_section_size(section);
if (data->pc >= vma + size)
return;
data->found = bfd_find_nearest_line(abfd, section, syms,
data->pc - vma,
&data->filename,
&data->function,
&data->line);
}
static void wpa_trace_bfd_addr(void *pc)
{
bfd *abfd = cached_abfd;
struct bfd_data data;
const char *name;
char *aname = NULL;
const char *filename;
if (abfd == NULL)
return;
data.pc = (bfd_vma) pc;
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
if (!data.found)
return;
do {
if (data.function)
aname = bfd_demangle(abfd, data.function,
DMGL_ANSI | DMGL_PARAMS);
name = aname ? aname : data.function;
filename = data.filename;
if (filename) {
char *end = os_strrchr(filename, '/');
int i = 0;
while (*filename && *filename == prg_fname[i] &&
filename <= end) {
filename++;
i++;
}
}
wpa_printf(MSG_INFO, " %s() %s:%u",
name, filename, data.line);
free(aname);
data.found = bfd_find_inliner_info(abfd, &data.filename,
&data.function, &data.line);
} while (data.found);
}
static const char * wpa_trace_bfd_addr2func(void *pc)
{
bfd *abfd = cached_abfd;
struct bfd_data data;
if (abfd == NULL)
return NULL;
data.pc = (bfd_vma) pc;
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
if (!data.found)
return NULL;
return data.function;
}
static void wpa_trace_bfd_init(void)
{
if (!prg_fname) {
get_prg_fname();
if (!prg_fname)
return;
}
if (!cached_abfd) {
cached_abfd = open_bfd(prg_fname);
if (!cached_abfd) {
wpa_printf(MSG_INFO, "Failed to open bfd");
return;
}
}
read_syms(cached_abfd);
if (!syms) {
wpa_printf(MSG_INFO, "Failed to read symbols");
return;
}
}
void wpa_trace_dump_funcname(const char *title, void *pc)
{
wpa_printf(MSG_INFO, "WPA_TRACE: %s: %p", title, pc);
wpa_trace_bfd_init();
wpa_trace_bfd_addr(pc);
}
#else /* WPA_TRACE_BFD */
#define wpa_trace_bfd_init() do { } while (0)
#define wpa_trace_bfd_addr(pc) do { } while (0)
#define wpa_trace_bfd_addr2func(pc) NULL
#endif /* WPA_TRACE_BFD */
void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num)
{
char **sym;
int i;
enum { TRACE_HEAD, TRACE_RELEVANT, TRACE_TAIL } state;
wpa_trace_bfd_init();
wpa_printf(MSG_INFO, "WPA_TRACE: %s - START", title);
sym = backtrace_symbols(btrace, btrace_num);
state = TRACE_HEAD;
for (i = 0; i < btrace_num; i++) {
const char *func = wpa_trace_bfd_addr2func(btrace[i]);
if (state == TRACE_HEAD && func &&
(os_strcmp(func, "wpa_trace_add_ref_func") == 0 ||
os_strcmp(func, "wpa_trace_check_ref") == 0 ||
os_strcmp(func, "wpa_trace_show") == 0))
continue;
if (state == TRACE_TAIL && sym && sym[i] &&
os_strstr(sym[i], "__libc_start_main"))
break;
if (state == TRACE_HEAD)
state = TRACE_RELEVANT;
if (sym)
wpa_printf(MSG_INFO, "[%d]: %s", i, sym[i]);
else
wpa_printf(MSG_INFO, "[%d]: ?? [%p]", i, btrace[i]);
wpa_trace_bfd_addr(btrace[i]);
if (state == TRACE_RELEVANT && func &&
os_strcmp(func, "main") == 0)
state = TRACE_TAIL;
}
free(sym);
wpa_printf(MSG_INFO, "WPA_TRACE: %s - END", title);
}
void wpa_trace_show(const char *title)
{
struct info {
WPA_TRACE_INFO
} info;
wpa_trace_record(&info);
wpa_trace_dump(title, &info);
}
void wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr)
{
if (addr == NULL)
return;
ref->addr = addr;
wpa_trace_record(ref);
dl_list_add(&active_references, &ref->list);
}
void wpa_trace_check_ref(const void *addr)
{
struct wpa_trace_ref *ref;
dl_list_for_each(ref, &active_references, struct wpa_trace_ref, list) {
if (addr != ref->addr)
continue;
wpa_trace_show("Freeing referenced memory");
wpa_trace_dump("Reference registration", ref);
abort();
}
}
#endif /* WPA_TRACE */

74
cipher/rsa/trace.h Normal file
View File

@ -0,0 +1,74 @@
/*
* Backtrace debugging
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef TRACE_H
#define TRACE_H
#define WPA_TRACE_LEN 16
#ifdef WPA_TRACE
#include <execinfo.h>
#include "list.h"
#define WPA_TRACE_INFO void *btrace[WPA_TRACE_LEN]; int btrace_num;
struct wpa_trace_ref {
struct dl_list list;
const void *addr;
WPA_TRACE_INFO
};
#define WPA_TRACE_REF(name) struct wpa_trace_ref wpa_trace_ref_##name
#define wpa_trace_dump(title, ptr) \
wpa_trace_dump_func((title), (ptr)->btrace, (ptr)->btrace_num)
void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num);
#define wpa_trace_record(ptr) \
(ptr)->btrace_num = backtrace((ptr)->btrace, WPA_TRACE_LEN)
void wpa_trace_show(const char *title);
#define wpa_trace_add_ref(ptr, name, addr) \
wpa_trace_add_ref_func(&(ptr)->wpa_trace_ref_##name, (addr))
void wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr);
#define wpa_trace_remove_ref(ptr, name, addr) \
do { \
if ((addr)) \
dl_list_del(&(ptr)->wpa_trace_ref_##name.list); \
} while (0)
void wpa_trace_check_ref(const void *addr);
#else /* WPA_TRACE */
#define WPA_TRACE_INFO
#define WPA_TRACE_REF(n)
#define wpa_trace_dump(title, ptr) do { } while (0)
#define wpa_trace_record(ptr) do { } while (0)
#define wpa_trace_show(title) do { } while (0)
#define wpa_trace_add_ref(ptr, name, addr) do { } while (0)
#define wpa_trace_remove_ref(ptr, name, addr) do { } while (0)
#define wpa_trace_check_ref(addr) do { } while (0)
#endif /* WPA_TRACE */
#ifdef WPA_TRACE_BFD
void wpa_trace_dump_funcname(const char *title, void *pc);
#else /* WPA_TRACE_BFD */
#define wpa_trace_dump_funcname(title, pc) do { } while (0)
#endif /* WPA_TRACE_BFD */
#endif /* TRACE_H */

94
cipher/rsa/user_rsa.c Normal file
View File

@ -0,0 +1,94 @@
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "base64.h"
#include "rsa.h"
#include "user_rsa.h"
static const u8 * search_tag(const char *tag, const u8 *buf, size_t len)
{
size_t i, plen;
plen = os_strlen(tag);
if (len < plen)
return NULL;
for (i = 0; i < len - plen; i++) {
if (os_memcmp(buf + i, tag, plen) == 0)
return buf + i;
}
return NULL;
}
static u8* get_key(const char *file, const char *start_tag, const char *end_tag, size_t *outlen)
{
size_t len;
u8 *buf = os_readfile(file, &len);
if (!buf)
return NULL;
const u8 *pos;
const u8 *end;
u8* der;
pos = search_tag(start_tag, buf, len);
if (!pos)
goto err;
pos += strlen(start_tag);
end = search_tag(end_tag, pos, buf + len - pos);
if (!end)
goto err;
der = base64_decode(pos, end-pos, outlen);
free(buf);
return der;
err:
if (buf)
free(buf);
return NULL;
}
void *RSA_Private_Init(const char *cert)
{
size_t l = 0;
u8* buf = get_key(cert, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----", &l);
if (!buf) {
fprintf(stderr, "get cert '%s' error\n", cert);
return NULL;
}
void *key = (void *)crypto_rsa_import_private_key(buf, l);
if (!key) {
fprintf(stderr, "import private key error\n");
return NULL;
}
os_free(buf);
return key;
}
int RSA_Private_Run(void *key, const void *src, size_t src_len, void *out, size_t *out_len)
{
struct crypto_rsa_key *rsa_key = (struct crypto_rsa_key*)key;
size_t mod_len = crypto_rsa_get_modulus_len(rsa_key);
if (mod_len < src_len)
return -1;
char *p = os_zalloc(mod_len);
if (!p)
return -2;
memcpy(p, src, src_len);
int ret = crypto_rsa_exptmod(p, mod_len, out, out_len, rsa_key, 1);
os_free(p);
return ret;
}
void RSA_Free(void *key)
{
crypto_rsa_free((struct crypto_rsa_key*)key);
}

19
cipher/rsa/user_rsa.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef _USER_RSA_H
#define _USER_RSA_H
#ifdef __cplusplus
extern "C"{
#endif
void *RSA_Private_Init(const char *cert);
int RSA_Private_Run(void *key, const void *src, size_t src_len, void *out, size_t *out_len);
void RSA_Free(void *key);
#ifdef __cplusplus
}
#endif
#endif

397
cipher/rsa/wpa_debug.c Normal file
View File

@ -0,0 +1,397 @@
/*
* wpa_supplicant/hostapd / Debug prints
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#ifdef CONFIG_DEBUG_SYSLOG
#include <syslog.h>
static int wpa_debug_syslog = 0;
#endif /* CONFIG_DEBUG_SYSLOG */
#ifdef CONFIG_DEBUG_FILE
static FILE *out_file = NULL;
#endif /* CONFIG_DEBUG_FILE */
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
int wpa_debug_timestamp = 0;
#ifndef CONFIG_NO_STDOUT_DEBUG
void wpa_debug_print_timestamp(void)
{
struct os_time tv;
if (!wpa_debug_timestamp)
return;
os_get_time(&tv);
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
(unsigned int) tv.usec);
} else
#endif /* CONFIG_DEBUG_FILE */
printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
}
#ifdef CONFIG_DEBUG_SYSLOG
void wpa_debug_open_syslog(void)
{
openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_DAEMON);
wpa_debug_syslog++;
}
void wpa_debug_close_syslog(void)
{
if (wpa_debug_syslog)
closelog();
}
static int syslog_priority(int level)
{
switch (level) {
case MSG_MSGDUMP:
case MSG_DEBUG:
return LOG_DEBUG;
case MSG_INFO:
return LOG_NOTICE;
case MSG_WARNING:
return LOG_WARNING;
case MSG_ERROR:
return LOG_ERR;
}
return LOG_INFO;
}
#endif /* CONFIG_DEBUG_SYSLOG */
/**
* wpa_printf - conditional printf
* @level: priority level (MSG_*) of the message
* @fmt: printf format string, followed by optional arguments
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration.
*
* Note: New line '\n' is added to the end of the text when printing to stdout.
*/
void wpa_printf(int level, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (level >= wpa_debug_level) {
#ifdef CONFIG_DEBUG_SYSLOG
if (wpa_debug_syslog) {
vsyslog(syslog_priority(level), fmt, ap);
} else {
#endif /* CONFIG_DEBUG_SYSLOG */
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
vfprintf(out_file, fmt, ap);
fprintf(out_file, "\n");
} else {
#endif /* CONFIG_DEBUG_FILE */
vprintf(fmt, ap);
printf("\n");
#ifdef CONFIG_DEBUG_FILE
}
#endif /* CONFIG_DEBUG_FILE */
#ifdef CONFIG_DEBUG_SYSLOG
}
#endif /* CONFIG_DEBUG_SYSLOG */
}
va_end(ap);
}
static void _wpa_hexdump(int level, const char *title, const u8 *buf,
size_t len, int show)
{
size_t i;
if (level < wpa_debug_level)
return;
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
fprintf(out_file, "%s - hexdump(len=%lu):",
title, (unsigned long) len);
if (buf == NULL) {
fprintf(out_file, " [NULL]");
} else if (show) {
for (i = 0; i < len; i++)
fprintf(out_file, " %02x", buf[i]);
} else {
fprintf(out_file, " [REMOVED]");
}
fprintf(out_file, "\n");
} else {
#endif /* CONFIG_DEBUG_FILE */
printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
if (buf == NULL) {
printf(" [NULL]");
} else if (show) {
for (i = 0; i < len; i++)
printf(" %02x", buf[i]);
} else {
printf(" [REMOVED]");
}
printf("\n");
#ifdef CONFIG_DEBUG_FILE
}
#endif /* CONFIG_DEBUG_FILE */
}
void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
{
_wpa_hexdump(level, title, buf, len, 1);
}
void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
{
_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
}
static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
size_t len, int show)
{
size_t i, llen;
const u8 *pos = buf;
const size_t line_len = 16;
if (level < wpa_debug_level)
return;
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
if (!show) {
fprintf(out_file,
"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
title, (unsigned long) len);
return;
}
if (buf == NULL) {
fprintf(out_file,
"%s - hexdump_ascii(len=%lu): [NULL]\n",
title, (unsigned long) len);
return;
}
fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
title, (unsigned long) len);
while (len) {
llen = len > line_len ? line_len : len;
fprintf(out_file, " ");
for (i = 0; i < llen; i++)
fprintf(out_file, " %02x", pos[i]);
for (i = llen; i < line_len; i++)
fprintf(out_file, " ");
fprintf(out_file, " ");
for (i = 0; i < llen; i++) {
if (isprint(pos[i]))
fprintf(out_file, "%c", pos[i]);
else
fprintf(out_file, "_");
}
for (i = llen; i < line_len; i++)
fprintf(out_file, " ");
fprintf(out_file, "\n");
pos += llen;
len -= llen;
}
} else {
#endif /* CONFIG_DEBUG_FILE */
if (!show) {
printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
title, (unsigned long) len);
return;
}
if (buf == NULL) {
printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
title, (unsigned long) len);
return;
}
printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
while (len) {
llen = len > line_len ? line_len : len;
printf(" ");
for (i = 0; i < llen; i++)
printf(" %02x", pos[i]);
for (i = llen; i < line_len; i++)
printf(" ");
printf(" ");
for (i = 0; i < llen; i++) {
if (isprint(pos[i]))
printf("%c", pos[i]);
else
printf("_");
}
for (i = llen; i < line_len; i++)
printf(" ");
printf("\n");
pos += llen;
len -= llen;
}
#ifdef CONFIG_DEBUG_FILE
}
#endif /* CONFIG_DEBUG_FILE */
}
void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
{
_wpa_hexdump_ascii(level, title, buf, len, 1);
}
void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
size_t len)
{
_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
}
int wpa_debug_open_file(const char *path)
{
#ifdef CONFIG_DEBUG_FILE
if (!path)
return 0;
out_file = fopen(path, "a");
if (out_file == NULL) {
wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
"output file, using standard output");
return -1;
}
#ifndef _WIN32
setvbuf(out_file, NULL, _IOLBF, 0);
#endif /* _WIN32 */
#endif /* CONFIG_DEBUG_FILE */
return 0;
}
void wpa_debug_close_file(void)
{
#ifdef CONFIG_DEBUG_FILE
if (!out_file)
return;
fclose(out_file);
out_file = NULL;
#endif /* CONFIG_DEBUG_FILE */
}
#endif /* CONFIG_NO_STDOUT_DEBUG */
#ifndef CONFIG_NO_WPA_MSG
static wpa_msg_cb_func wpa_msg_cb = NULL;
void wpa_msg_register_cb(wpa_msg_cb_func func)
{
wpa_msg_cb = func;
}
void wpa_msg(void *ctx, int level, const char *fmt, ...)
{
va_list ap;
char *buf;
const int buflen = 2048;
int len;
buf = os_malloc(buflen);
if (buf == NULL) {
wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
"buffer");
return;
}
va_start(ap, fmt);
len = vsnprintf(buf, buflen, fmt, ap);
va_end(ap);
wpa_printf(level, "%s", buf);
if (wpa_msg_cb)
wpa_msg_cb(ctx, level, buf, len);
os_free(buf);
}
void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
{
va_list ap;
char *buf;
const int buflen = 2048;
int len;
if (!wpa_msg_cb)
return;
buf = os_malloc(buflen);
if (buf == NULL) {
wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
"message buffer");
return;
}
va_start(ap, fmt);
len = vsnprintf(buf, buflen, fmt, ap);
va_end(ap);
wpa_msg_cb(ctx, level, buf, len);
os_free(buf);
}
#endif /* CONFIG_NO_WPA_MSG */
#ifndef CONFIG_NO_HOSTAPD_LOGGER
static hostapd_logger_cb_func hostapd_logger_cb = NULL;
void hostapd_logger_register_cb(hostapd_logger_cb_func func)
{
hostapd_logger_cb = func;
}
void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
const char *fmt, ...)
{
va_list ap;
char *buf;
const int buflen = 2048;
int len;
buf = os_malloc(buflen);
if (buf == NULL) {
wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
"message buffer");
return;
}
va_start(ap, fmt);
len = vsnprintf(buf, buflen, fmt, ap);
va_end(ap);
if (hostapd_logger_cb)
hostapd_logger_cb(ctx, addr, module, level, buf, len);
else
wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
os_free(buf);
}
#endif /* CONFIG_NO_HOSTAPD_LOGGER */

256
cipher/rsa/wpa_debug.h Normal file
View File

@ -0,0 +1,256 @@
/*
* wpa_supplicant/hostapd / Debug prints
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef WPA_DEBUG_H
#define WPA_DEBUG_H
#include "wpabuf.h"
/* Debugging function - conditional printf and hex dump. Driver wrappers can
* use these for debugging purposes. */
enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR };
#ifdef CONFIG_NO_STDOUT_DEBUG
#define wpa_debug_print_timestamp() do { } while (0)
#define wpa_printf(args...) do { } while (0)
#define wpa_hexdump(l,t,b,le) do { } while (0)
#define wpa_hexdump_buf(l,t,b) do { } while (0)
#define wpa_hexdump_key(l,t,b,le) do { } while (0)
#define wpa_hexdump_buf_key(l,t,b) do { } while (0)
#define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
#define wpa_debug_open_file(p) do { } while (0)
#define wpa_debug_close_file() do { } while (0)
#else /* CONFIG_NO_STDOUT_DEBUG */
int wpa_debug_open_file(const char *path);
void wpa_debug_close_file(void);
/**
* wpa_debug_printf_timestamp - Print timestamp for debug output
*
* This function prints a timestamp in seconds_from_1970.microsoconds
* format if debug output has been configured to include timestamps in debug
* messages.
*/
void wpa_debug_print_timestamp(void);
/**
* wpa_printf - conditional printf
* @level: priority level (MSG_*) of the message
* @fmt: printf format string, followed by optional arguments
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration.
*
* Note: New line '\n' is added to the end of the text when printing to stdout.
*/
void wpa_printf(int level, const char *fmt, ...)
PRINTF_FORMAT(2, 3);
/**
* wpa_hexdump - conditional hex dump
* @level: priority level (MSG_*) of the message
* @title: title of for the message
* @buf: data buffer to be dumped
* @len: length of the buf
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration. The contents of buf is printed out has hex dump.
*/
void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len);
static inline void wpa_hexdump_buf(int level, const char *title,
const struct wpabuf *buf)
{
wpa_hexdump(level, title, wpabuf_head(buf), wpabuf_len(buf));
}
/**
* wpa_hexdump_key - conditional hex dump, hide keys
* @level: priority level (MSG_*) of the message
* @title: title of for the message
* @buf: data buffer to be dumped
* @len: length of the buf
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration. The contents of buf is printed out has hex dump. This works
* like wpa_hexdump(), but by default, does not include secret keys (passwords,
* etc.) in debug output.
*/
void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len);
static inline void wpa_hexdump_buf_key(int level, const char *title,
const struct wpabuf *buf)
{
wpa_hexdump_key(level, title, wpabuf_head(buf), wpabuf_len(buf));
}
/**
* wpa_hexdump_ascii - conditional hex dump
* @level: priority level (MSG_*) of the message
* @title: title of for the message
* @buf: data buffer to be dumped
* @len: length of the buf
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration. The contents of buf is printed out has hex dump with both
* the hex numbers and ASCII characters (for printable range) are shown. 16
* bytes per line will be shown.
*/
void wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
size_t len);
/**
* wpa_hexdump_ascii_key - conditional hex dump, hide keys
* @level: priority level (MSG_*) of the message
* @title: title of for the message
* @buf: data buffer to be dumped
* @len: length of the buf
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration. The contents of buf is printed out has hex dump with both
* the hex numbers and ASCII characters (for printable range) are shown. 16
* bytes per line will be shown. This works like wpa_hexdump_ascii(), but by
* default, does not include secret keys (passwords, etc.) in debug output.
*/
void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
size_t len);
#endif /* CONFIG_NO_STDOUT_DEBUG */
#ifdef CONFIG_NO_WPA_MSG
#define wpa_msg(args...) do { } while (0)
#define wpa_msg_ctrl(args...) do { } while (0)
#define wpa_msg_register_cb(f) do { } while (0)
#else /* CONFIG_NO_WPA_MSG */
/**
* wpa_msg - Conditional printf for default target and ctrl_iface monitors
* @ctx: Pointer to context data; this is the ctx variable registered
* with struct wpa_driver_ops::init()
* @level: priority level (MSG_*) of the message
* @fmt: printf format string, followed by optional arguments
*
* This function is used to print conditional debugging and error messages. The
* output may be directed to stdout, stderr, and/or syslog based on
* configuration. This function is like wpa_printf(), but it also sends the
* same message to all attached ctrl_iface monitors.
*
* Note: New line '\n' is added to the end of the text when printing to stdout.
*/
void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4);
/**
* wpa_msg_ctrl - Conditional printf for ctrl_iface monitors
* @ctx: Pointer to context data; this is the ctx variable registered
* with struct wpa_driver_ops::init()
* @level: priority level (MSG_*) of the message
* @fmt: printf format string, followed by optional arguments
*
* This function is used to print conditional debugging and error messages.
* This function is like wpa_msg(), but it sends the output only to the
* attached ctrl_iface monitors. In other words, it can be used for frequent
* events that do not need to be sent to syslog.
*/
void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
PRINTF_FORMAT(3, 4);
typedef void (*wpa_msg_cb_func)(void *ctx, int level, const char *txt,
size_t len);
/**
* wpa_msg_register_cb - Register callback function for wpa_msg() messages
* @func: Callback function (%NULL to unregister)
*/
void wpa_msg_register_cb(wpa_msg_cb_func func);
#endif /* CONFIG_NO_WPA_MSG */
#ifdef CONFIG_NO_HOSTAPD_LOGGER
#define hostapd_logger(args...) do { } while (0)
#define hostapd_logger_register_cb(f) do { } while (0)
#else /* CONFIG_NO_HOSTAPD_LOGGER */
void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
const char *fmt, ...) PRINTF_FORMAT(5, 6);
typedef void (*hostapd_logger_cb_func)(void *ctx, const u8 *addr,
unsigned int module, int level,
const char *txt, size_t len);
/**
* hostapd_logger_register_cb - Register callback function for hostapd_logger()
* @func: Callback function (%NULL to unregister)
*/
void hostapd_logger_register_cb(hostapd_logger_cb_func func);
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
#define HOSTAPD_MODULE_IEEE80211 0x00000001
#define HOSTAPD_MODULE_IEEE8021X 0x00000002
#define HOSTAPD_MODULE_RADIUS 0x00000004
#define HOSTAPD_MODULE_WPA 0x00000008
#define HOSTAPD_MODULE_DRIVER 0x00000010
#define HOSTAPD_MODULE_IAPP 0x00000020
#define HOSTAPD_MODULE_MLME 0x00000040
enum hostapd_logger_level {
HOSTAPD_LEVEL_DEBUG_VERBOSE = 0,
HOSTAPD_LEVEL_DEBUG = 1,
HOSTAPD_LEVEL_INFO = 2,
HOSTAPD_LEVEL_NOTICE = 3,
HOSTAPD_LEVEL_WARNING = 4
};
#ifdef CONFIG_DEBUG_SYSLOG
void wpa_debug_open_syslog(void);
void wpa_debug_close_syslog(void);
#else /* CONFIG_DEBUG_SYSLOG */
static inline void wpa_debug_open_syslog(void)
{
}
static inline void wpa_debug_close_syslog(void)
{
}
#endif /* CONFIG_DEBUG_SYSLOG */
#ifdef EAPOL_TEST
#define WPA_ASSERT(a) \
do { \
if (!(a)) { \
printf("WPA_ASSERT FAILED '" #a "' " \
"%s %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
exit(1); \
} \
} while (0)
#else
#define WPA_ASSERT(a) do { } while (0)
#endif
#endif /* WPA_DEBUG_H */

304
cipher/rsa/wpabuf.c Normal file
View File

@ -0,0 +1,304 @@
/*
* Dynamic data buffer
* Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "trace.h"
#include "wpabuf.h"
#ifdef WPA_TRACE
#define WPABUF_MAGIC 0x51a974e3
struct wpabuf_trace {
unsigned int magic;
};
static struct wpabuf_trace * wpabuf_get_trace(const struct wpabuf *buf)
{
return (struct wpabuf_trace *)
((const u8 *) buf - sizeof(struct wpabuf_trace));
}
#endif /* WPA_TRACE */
static void wpabuf_overflow(const struct wpabuf *buf, size_t len)
{
#ifdef WPA_TRACE
struct wpabuf_trace *trace = wpabuf_get_trace(buf);
if (trace->magic != WPABUF_MAGIC) {
wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x",
trace->magic);
}
#endif /* WPA_TRACE */
wpa_printf(MSG_ERROR, "wpabuf %p (size=%lu used=%lu) overflow len=%lu",
buf, (unsigned long) buf->size, (unsigned long) buf->used,
(unsigned long) len);
wpa_trace_show("wpabuf overflow");
abort();
}
int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
{
struct wpabuf *buf = *_buf;
#ifdef WPA_TRACE
struct wpabuf_trace *trace;
#endif /* WPA_TRACE */
if (buf == NULL) {
*_buf = wpabuf_alloc(add_len);
return *_buf == NULL ? -1 : 0;
}
#ifdef WPA_TRACE
trace = wpabuf_get_trace(buf);
if (trace->magic != WPABUF_MAGIC) {
wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x",
trace->magic);
wpa_trace_show("wpabuf_resize invalid magic");
abort();
}
#endif /* WPA_TRACE */
if (buf->used + add_len > buf->size) {
unsigned char *nbuf;
if (buf->ext_data) {
nbuf = os_realloc(buf->ext_data, buf->used + add_len);
if (nbuf == NULL)
return -1;
os_memset(nbuf + buf->used, 0, add_len);
buf->ext_data = nbuf;
} else {
#ifdef WPA_TRACE
nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) +
sizeof(struct wpabuf) +
buf->used + add_len);
if (nbuf == NULL)
return -1;
trace = (struct wpabuf_trace *) nbuf;
buf = (struct wpabuf *) (trace + 1);
os_memset(nbuf + sizeof(struct wpabuf_trace) +
sizeof(struct wpabuf) + buf->used, 0,
add_len);
#else /* WPA_TRACE */
nbuf = os_realloc(buf, sizeof(struct wpabuf) +
buf->used + add_len);
if (nbuf == NULL)
return -1;
buf = (struct wpabuf *) nbuf;
os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0,
add_len);
#endif /* WPA_TRACE */
*_buf = buf;
}
buf->size = buf->used + add_len;
}
return 0;
}
/**
* wpabuf_alloc - Allocate a wpabuf of the given size
* @len: Length for the allocated buffer
* Returns: Buffer to the allocated wpabuf or %NULL on failure
*/
struct wpabuf * wpabuf_alloc(size_t len)
{
#ifdef WPA_TRACE
struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) +
sizeof(struct wpabuf) + len);
struct wpabuf *buf;
if (trace == NULL)
return NULL;
trace->magic = WPABUF_MAGIC;
buf = (struct wpabuf *) (trace + 1);
#else /* WPA_TRACE */
struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf) + len);
if (buf == NULL)
return NULL;
#endif /* WPA_TRACE */
buf->size = len;
return buf;
}
struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len)
{
#ifdef WPA_TRACE
struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) +
sizeof(struct wpabuf));
struct wpabuf *buf;
if (trace == NULL)
return NULL;
trace->magic = WPABUF_MAGIC;
buf = (struct wpabuf *) (trace + 1);
#else /* WPA_TRACE */
struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf));
if (buf == NULL)
return NULL;
#endif /* WPA_TRACE */
buf->size = len;
buf->used = len;
buf->ext_data = data;
return buf;
}
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len)
{
struct wpabuf *buf = wpabuf_alloc(len);
if (buf)
wpabuf_put_data(buf, data, len);
return buf;
}
struct wpabuf * wpabuf_dup(const struct wpabuf *src)
{
struct wpabuf *buf = wpabuf_alloc(wpabuf_len(src));
if (buf)
wpabuf_put_data(buf, wpabuf_head(src), wpabuf_len(src));
return buf;
}
/**
* wpabuf_free - Free a wpabuf
* @buf: wpabuf buffer
*/
void wpabuf_free(struct wpabuf *buf)
{
#ifdef WPA_TRACE
struct wpabuf_trace *trace;
if (buf == NULL)
return;
trace = wpabuf_get_trace(buf);
if (trace->magic != WPABUF_MAGIC) {
wpa_printf(MSG_ERROR, "wpabuf_free: invalid magic %x",
trace->magic);
wpa_trace_show("wpabuf_free magic mismatch");
abort();
}
os_free(buf->ext_data);
os_free(trace);
#else /* WPA_TRACE */
if (buf == NULL)
return;
os_free(buf->ext_data);
os_free(buf);
#endif /* WPA_TRACE */
}
void * wpabuf_put(struct wpabuf *buf, size_t len)
{
void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
buf->used += len;
if (buf->used > buf->size) {
wpabuf_overflow(buf, len);
}
return tmp;
}
/**
* wpabuf_concat - Concatenate two buffers into a newly allocated one
* @a: First buffer
* @b: Second buffer
* Returns: wpabuf with concatenated a + b data or %NULL on failure
*
* Both buffers a and b will be freed regardless of the return value. Input
* buffers can be %NULL which is interpreted as an empty buffer.
*/
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b)
{
struct wpabuf *n = NULL;
size_t len = 0;
if (b == NULL)
return a;
if (a)
len += wpabuf_len(a);
if (b)
len += wpabuf_len(b);
n = wpabuf_alloc(len);
if (n) {
if (a)
wpabuf_put_buf(n, a);
if (b)
wpabuf_put_buf(n, b);
}
wpabuf_free(a);
wpabuf_free(b);
return n;
}
/**
* wpabuf_zeropad - Pad buffer with 0x00 octets (prefix) to specified length
* @buf: Buffer to be padded
* @len: Length for the padded buffer
* Returns: wpabuf padded to len octets or %NULL on failure
*
* If buf is longer than len octets or of same size, it will be returned as-is.
* Otherwise a new buffer is allocated and prefixed with 0x00 octets followed
* by the source data. The source buffer will be freed on error, i.e., caller
* will only be responsible on freeing the returned buffer. If buf is %NULL,
* %NULL will be returned.
*/
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len)
{
struct wpabuf *ret;
size_t blen;
if (buf == NULL)
return NULL;
blen = wpabuf_len(buf);
if (blen >= len)
return buf;
ret = wpabuf_alloc(len);
if (ret) {
os_memset(wpabuf_put(ret, len - blen), 0, len - blen);
wpabuf_put_buf(ret, buf);
}
wpabuf_free(buf);
return ret;
}
void wpabuf_printf(struct wpabuf *buf, char *fmt, ...)
{
va_list ap;
void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
int res;
va_start(ap, fmt);
res = vsnprintf(tmp, buf->size - buf->used, fmt, ap);
va_end(ap);
if (res < 0 || (size_t) res >= buf->size - buf->used)
wpabuf_overflow(buf, res);
buf->used += res;
}

162
cipher/rsa/wpabuf.h Normal file
View File

@ -0,0 +1,162 @@
/*
* Dynamic data buffer
* Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef WPABUF_H
#define WPABUF_H
/*
* Internal data structure for wpabuf. Please do not touch this directly from
* elsewhere. This is only defined in header file to allow inline functions
* from this file to access data.
*/
struct wpabuf {
size_t size; /* total size of the allocated buffer */
size_t used; /* length of data in the buffer */
u8 *ext_data; /* pointer to external data; NULL if data follows
* struct wpabuf */
/* optionally followed by the allocated buffer */
};
int wpabuf_resize(struct wpabuf **buf, size_t add_len);
struct wpabuf * wpabuf_alloc(size_t len);
struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len);
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len);
struct wpabuf * wpabuf_dup(const struct wpabuf *src);
void wpabuf_free(struct wpabuf *buf);
void * wpabuf_put(struct wpabuf *buf, size_t len);
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b);
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len);
void wpabuf_printf(struct wpabuf *buf, char *fmt, ...) PRINTF_FORMAT(2, 3);
/**
* wpabuf_size - Get the currently allocated size of a wpabuf buffer
* @buf: wpabuf buffer
* Returns: Currently allocated size of the buffer
*/
static inline size_t wpabuf_size(const struct wpabuf *buf)
{
return buf->size;
}
/**
* wpabuf_len - Get the current length of a wpabuf buffer data
* @buf: wpabuf buffer
* Returns: Currently used length of the buffer
*/
static inline size_t wpabuf_len(const struct wpabuf *buf)
{
return buf->used;
}
/**
* wpabuf_tailroom - Get size of available tail room in the end of the buffer
* @buf: wpabuf buffer
* Returns: Tail room (in bytes) of available space in the end of the buffer
*/
static inline size_t wpabuf_tailroom(const struct wpabuf *buf)
{
return buf->size - buf->used;
}
/**
* wpabuf_head - Get pointer to the head of the buffer data
* @buf: wpabuf buffer
* Returns: Pointer to the head of the buffer data
*/
static inline const void * wpabuf_head(const struct wpabuf *buf)
{
if (buf->ext_data)
return buf->ext_data;
return buf + 1;
}
static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf)
{
return wpabuf_head(buf);
}
/**
* wpabuf_mhead - Get modifiable pointer to the head of the buffer data
* @buf: wpabuf buffer
* Returns: Pointer to the head of the buffer data
*/
static inline void * wpabuf_mhead(struct wpabuf *buf)
{
if (buf->ext_data)
return buf->ext_data;
return buf + 1;
}
static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf)
{
return wpabuf_mhead(buf);
}
static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data)
{
u8 *pos = wpabuf_put(buf, 1);
*pos = data;
}
static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data)
{
u8 *pos = wpabuf_put(buf, 2);
WPA_PUT_LE16(pos, data);
}
static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data)
{
u8 *pos = wpabuf_put(buf, 2);
WPA_PUT_BE16(pos, data);
}
static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data)
{
u8 *pos = wpabuf_put(buf, 3);
WPA_PUT_BE24(pos, data);
}
static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data)
{
u8 *pos = wpabuf_put(buf, 4);
WPA_PUT_BE32(pos, data);
}
static inline void wpabuf_put_data(struct wpabuf *buf, const void *data,
size_t len)
{
if (data)
os_memcpy(wpabuf_put(buf, len), data, len);
}
static inline void wpabuf_put_buf(struct wpabuf *dst,
const struct wpabuf *src)
{
wpabuf_put_data(dst, wpabuf_head(src), wpabuf_len(src));
}
static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len)
{
buf->ext_data = (u8 *) data;
buf->size = buf->used = len;
}
static inline void wpabuf_put_str(struct wpabuf *dst, const char *str)
{
wpabuf_put_data(dst, str, os_strlen(str));
}
#endif /* WPABUF_H */

222
cipher/sha.c Normal file
View File

@ -0,0 +1,222 @@
/*
* SHA1 hash algorithm. Used in SSH-2 as a MAC, and the transform is
* also used as a `stirring' function for the PuTTY random number
* pool. Implemented directly from the specification by Simon
* Tatham.
*/
#include <string.h>
#include "sha.h"
/* ----------------------------------------------------------------------
* Core SHA algorithm: processes 16-word blocks into a message digest.
*/
#define rol(x,y) ( ((x) << (y)) | (((uint32)x) >> (32-y)) )
#define PUT_32BIT_MSB_FIRST(cp, value) ( \
(cp)[0] = (unsigned char)((value) >> 24), \
(cp)[1] = (unsigned char)((value) >> 16), \
(cp)[2] = (unsigned char)((value) >> 8), \
(cp)[3] = (unsigned char)(value) )
static void SHA_Core_Init(uint32 h[5])
{
h[0] = 0x67452301;
h[1] = 0xefcdab89;
h[2] = 0x98badcfe;
h[3] = 0x10325476;
h[4] = 0xc3d2e1f0;
}
void SHATransform(word32 * digest, word32 * block)
{
word32 w[80];
word32 a, b, c, d, e;
int t;
#ifdef RANDOM_DIAGNOSTICS
{
extern int random_diagnostics;
if (random_diagnostics) {
int i;
printf("SHATransform:");
for (i = 0; i < 5; i++)
printf(" %08x", digest[i]);
printf(" +");
for (i = 0; i < 16; i++)
printf(" %08x", block[i]);
}
}
#endif
for (t = 0; t < 16; t++)
w[t] = block[t];
for (t = 16; t < 80; t++) {
word32 tmp = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
w[t] = rol(tmp, 1);
}
a = digest[0];
b = digest[1];
c = digest[2];
d = digest[3];
e = digest[4];
for (t = 0; t < 20; t++) {
word32 tmp =
rol(a, 5) + ((b & c) | (d & ~b)) + e + w[t] + 0x5a827999;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
for (t = 20; t < 40; t++) {
word32 tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ed9eba1;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
for (t = 40; t < 60; t++) {
word32 tmp = rol(a,
5) + ((b & c) | (b & d) | (c & d)) + e + w[t] +
0x8f1bbcdc;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
for (t = 60; t < 80; t++) {
word32 tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0xca62c1d6;
e = d;
d = c;
c = rol(b, 30);
b = a;
a = tmp;
}
digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
digest[4] += e;
#ifdef RANDOM_DIAGNOSTICS
{
extern int random_diagnostics;
if (random_diagnostics) {
int i;
printf(" =");
for (i = 0; i < 5; i++)
printf(" %08x", digest[i]);
printf("\n");
}
}
#endif
}
/* ----------------------------------------------------------------------
* Outer SHA algorithm: take an arbitrary length byte string,
* convert it into 16-word blocks with the prescribed padding at
* the end, and pass those blocks to the core SHA algorithm.
*/
void SHA_Init(SHA_State * s)
{
SHA_Core_Init(s->h);
s->blkused = 0;
s->lenhi = s->lenlo = 0;
}
void SHA_Bytes(SHA_State * s, const void *p, int len)
{
const unsigned char *q = (const unsigned char *) p;
uint32 wordblock[16];
uint32 lenw = len;
int i;
/*
* Update the length field.
*/
s->lenlo += lenw;
s->lenhi += (s->lenlo < lenw);
if (s->blkused && s->blkused + len < 64) {
/*
* Trivial case: just add to the block.
*/
memcpy(s->block + s->blkused, q, len);
s->blkused += len;
} else {
/*
* We must complete and process at least one block.
*/
while (s->blkused + len >= 64) {
memcpy(s->block + s->blkused, q, 64 - s->blkused);
q += 64 - s->blkused;
len -= 64 - s->blkused;
/* Now process the block. Gather bytes big-endian into words */
for (i = 0; i < 16; i++) {
wordblock[i] =
(((uint32) s->block[i * 4 + 0]) << 24) |
(((uint32) s->block[i * 4 + 1]) << 16) |
(((uint32) s->block[i * 4 + 2]) << 8) |
(((uint32) s->block[i * 4 + 3]) << 0);
}
SHATransform(s->h, wordblock);
s->blkused = 0;
}
memcpy(s->block, q, len);
s->blkused = len;
}
}
void SHA_Final(SHA_State * s, unsigned char *output)
{
int i;
int pad;
unsigned char c[64];
uint32 lenhi, lenlo;
if (s->blkused >= 56)
pad = 56 + 64 - s->blkused;
else
pad = 56 - s->blkused;
lenhi = (s->lenhi << 3) | (s->lenlo >> (32 - 3));
lenlo = (s->lenlo << 3);
memset(c, 0, pad);
c[0] = 0x80;
SHA_Bytes(s, &c, pad);
c[0] = (lenhi >> 24) & 0xFF;
c[1] = (lenhi >> 16) & 0xFF;
c[2] = (lenhi >> 8) & 0xFF;
c[3] = (lenhi >> 0) & 0xFF;
c[4] = (lenlo >> 24) & 0xFF;
c[5] = (lenlo >> 16) & 0xFF;
c[6] = (lenlo >> 8) & 0xFF;
c[7] = (lenlo >> 0) & 0xFF;
SHA_Bytes(s, &c, 8);
for (i = 0; i < 5; i++) {
output[i * 4] = (s->h[i] >> 24) & 0xFF;
output[i * 4 + 1] = (s->h[i] >> 16) & 0xFF;
output[i * 4 + 2] = (s->h[i] >> 8) & 0xFF;
output[i * 4 + 3] = (s->h[i]) & 0xFF;
}
}
void SHA_Simple(const void *p, int len, unsigned char *output)
{
SHA_State s;
SHA_Init(&s);
SHA_Bytes(&s, p, len);
SHA_Final(&s, output);
}

21
cipher/sha.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _CIPHER_SHASHA_H
#define _CIPHER_SHASHA_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef unsigned int uint32;
typedef uint32 word32;
typedef struct {
uint32 h[5];
unsigned char block[64];
int blkused;
uint32 lenhi, lenlo;
} SHA_State;
void SHA_Init(SHA_State * s);
void SHA_Bytes(SHA_State * s, const void *p, int len);
void SHA_Final(SHA_State * s, unsigned char *output);
void SHA_Simple(const void *p, int len, unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_SHASHA_H */

296
cipher/sha1.c Normal file
View File

@ -0,0 +1,296 @@
/* from valgrind tests */
/* ================ sha1.c ================ */
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#define SHA1HANDSOFF
#include <stdio.h>
#include <string.h>
#include <sys/types.h> /* for u_int*_t */
#if defined(__sun)
#include "solarisfixes.h"
#endif
#include "sha1.h"
#ifndef BYTE_ORDER
#if (BSD >= 199103)
# include <machine/endian.h>
#else
#if defined(linux) || defined(__linux__)
# include <endian.h>
#else
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
#if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \
defined(vax) || defined(ns32000) || defined(sun386) || \
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
defined(__alpha__) || defined(__alpha)
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \
defined(__hppa) || defined(__hp9000) || \
defined(__hp9000s300) || defined(__hp9000s700) || \
defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc)
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* linux */
#endif /* BSD */
#endif /* BYTE_ORDER */
/* Sometimes after including an OS-specific header that defines the
* endianess we end with __BYTE_ORDER but not with BYTE_ORDER that is what
* the Redis code uses. In this case let's define everything without the
* underscores. */
#ifndef BYTE_ORDER
#ifdef __BYTE_ORDER
#if defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN __BIG_ENDIAN
#endif
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#else
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif
#endif
#endif
#if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN)
/* you must determine what the correct bit order is for
* your compiler - the next line is an intentional error
* which will force your compiles to bomb until you fix
* the above macros.
*/
#error "Undefined or invalid BYTE_ORDER"
#endif
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if BYTE_ORDER == LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#elif BYTE_ORDER == BIG_ENDIAN
#define blk0(i) block->l[i]
#else
#error "Endianness not defined!"
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
{
unsigned int a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned int l[16];
} CHAR64LONG16;
#ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
memcpy(block, buffer, 64);
#else
/* The following had better never be used because it causes the
* pointer-to-const buffer to be cast into a pointer to non-const.
* And the result is written through. I threw a "const" in, hoping
* this will cause a diagnostic.
*/
CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF
memset(block, '\0', sizeof(block));
#endif
}
/* SHA1Init - Initialize new context */
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = context->count[0];
if ((context->count[0] += len << 3) < j)
context->count[1]++;
context->count[1] += (len>>29);
j = (j >> 3) & 63;
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for (; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
{
unsigned i;
unsigned char finalcount[8];
unsigned char c;
#if 0 /* untested "improvement" by DHR */
/* Convert context->count to a sequence of bytes
* in finalcount. Second element first, but
* big-endian order within element.
* But we do it all backwards.
*/
unsigned char *fcp = &finalcount[8];
for (i = 0; i < 2; i++)
{
unsigned int t = context->count[i];
int j;
for (j = 0; j < 4; t >>= 8, j++)
*--fcp = (unsigned char) t;
}
#else
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8)) & 255); /* Endian independent */
}
#endif
c = 0200;
SHA1Update(context, &c, 1);
while ((context->count[0] & 504) != 448) {
c = 0000;
SHA1Update(context, &c, 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8)) & 255);
}
/* Wipe variables */
memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount));
}
void SHA1Calc(const unsigned char *input, unsigned int inlen, unsigned char *output) {
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, input, inlen);
SHA1Final(output, &ctx);
}
/* ================ end of sha1.cpp ================ */
#if 0
#define BUFSIZE 4096
int
main(int argc, char **argv)
{
SHA1_CTX ctx;
unsigned char hash[20], buf[BUFSIZE];
int i;
for(i=0;i<BUFSIZE;i++)
buf[i] = i;
SHA1Init(&ctx);
for(i=0;i<1000;i++)
SHA1Update(&ctx, buf, BUFSIZE);
SHA1Final(hash, &ctx);
printf("SHA1=");
for(i=0;i<20;i++)
printf("%02x", hash[i]);
printf("\n");
return 0;
}
#endif

28
cipher/sha1.h Normal file
View File

@ -0,0 +1,28 @@
/* ================ sha1.h ================ */
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
*/
#ifndef _SYS_SHA1_H_
#define _SYS_SHA1_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct {
unsigned int state[5];
unsigned int count[2];
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
// The function to calculate the message digest string
// of a given string based on the SHA1 algrithm.
void SHA1Calc(const unsigned char *input, unsigned int inlen, unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _SYS_SHA1_H_ */

38
cipher/sha224.c Normal file
View File

@ -0,0 +1,38 @@
#include <string.h>
#include "sha224.h"
void SHA224_Core_Init(SHA256_State *s) {
s->h[0] = 0xc1059ed8ul;
s->h[1] = 0x367cd507ul;
s->h[2] = 0x3070dd17ul;
s->h[3] = 0xf70e5939ul;
s->h[4] = 0xffc00b31ul;
s->h[5] = 0x68581511ul;
s->h[6] = 0x64f98fa7ul;
s->h[7] = 0xbefa4fa4ul;
}
#define SHA224_DIGEST_SIZE 28
void SHA224_Init(SHA256_State *s) {
SHA224_Core_Init(s);
s->blkused = 0;
s->lenhi = s->lenlo = 0;
}
void SHA224_Bytes(SHA256_State *s, const void *p, int len) {
SHA256_Bytes(s, p, len);
}
void SHA224_Final(SHA256_State *s, unsigned char *digest) {
SHA256_Final(s, digest);
digest[SHA224_DIGEST_SIZE] = 0x00;
}
void SHA224_Simple(const void *p, int len, unsigned char *output) {
SHA256_State s;
SHA224_Init(&s);
SHA224_Bytes(&s, p, len);
SHA224_Final(&s, output);
}

15
cipher/sha224.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _CIPHER_SHA224_H
#define _CIPHER_SHA224_H
#include "sha256.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void SHA224_Init(SHA256_State * s);
void SHA224_Bytes(SHA256_State * s, const void *p, int len);
void SHA224_Final(SHA256_State * s, unsigned char *output);
void SHA224_Simple(const void *p, int len, unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_SHA224_H */

243
cipher/sha256.c Normal file
View File

@ -0,0 +1,243 @@
/*
* SHA-256 algorithm as described at
*
* http://csrc.nist.gov/cryptval/shs.html
*/
#include <string.h>
#include "sha256.h"
//#define TEST
/* ----------------------------------------------------------------------
* Core SHA256 algorithm: processes 16-word blocks into a message digest.
*/
#define ror(x,y) ( ((x) << (32-y)) | (((uint32)(x)) >> (y)) )
#define shr(x,y) ( (((uint32)(x)) >> (y)) )
#define Ch(x,y,z) ( ((x) & (y)) ^ (~(x) & (z)) )
#define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) )
#define bigsigma0(x) ( ror((x),2) ^ ror((x),13) ^ ror((x),22) )
#define bigsigma1(x) ( ror((x),6) ^ ror((x),11) ^ ror((x),25) )
#define smallsigma0(x) ( ror((x),7) ^ ror((x),18) ^ shr((x),3) )
#define smallsigma1(x) ( ror((x),17) ^ ror((x),19) ^ shr((x),10) )
#define PUT_32BIT_MSB_FIRST(cp, value) ( \
(cp)[0] = (unsigned char)((value) >> 24), \
(cp)[1] = (unsigned char)((value) >> 16), \
(cp)[2] = (unsigned char)((value) >> 8), \
(cp)[3] = (unsigned char)(value) )
void SHA256_Core_Init(SHA256_State *s) {
s->h[0] = 0x6a09e667;
s->h[1] = 0xbb67ae85;
s->h[2] = 0x3c6ef372;
s->h[3] = 0xa54ff53a;
s->h[4] = 0x510e527f;
s->h[5] = 0x9b05688c;
s->h[6] = 0x1f83d9ab;
s->h[7] = 0x5be0cd19;
}
void SHA256_Block(SHA256_State *s, uint32 *block) {
uint32 w[80];
uint32 a,b,c,d,e,f,g,h;
static const int k[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
};
int t;
for (t = 0; t < 16; t++)
w[t] = block[t];
for (t = 16; t < 64; t++)
w[t] = smallsigma1(w[t-2]) + w[t-7] + smallsigma0(w[t-15]) + w[t-16];
a = s->h[0]; b = s->h[1]; c = s->h[2]; d = s->h[3];
e = s->h[4]; f = s->h[5]; g = s->h[6]; h = s->h[7];
for (t = 0; t < 64; t+=8) {
uint32 t1, t2;
#define ROUND(j,a,b,c,d,e,f,g,h) \
t1 = h + bigsigma1(e) + Ch(e,f,g) + k[j] + w[j]; \
t2 = bigsigma0(a) + Maj(a,b,c); \
d = d + t1; h = t1 + t2;
ROUND(t+0, a,b,c,d,e,f,g,h);
ROUND(t+1, h,a,b,c,d,e,f,g);
ROUND(t+2, g,h,a,b,c,d,e,f);
ROUND(t+3, f,g,h,a,b,c,d,e);
ROUND(t+4, e,f,g,h,a,b,c,d);
ROUND(t+5, d,e,f,g,h,a,b,c);
ROUND(t+6, c,d,e,f,g,h,a,b);
ROUND(t+7, b,c,d,e,f,g,h,a);
}
s->h[0] += a; s->h[1] += b; s->h[2] += c; s->h[3] += d;
s->h[4] += e; s->h[5] += f; s->h[6] += g; s->h[7] += h;
}
/* ----------------------------------------------------------------------
* Outer SHA256 algorithm: take an arbitrary length byte string,
* convert it into 16-word blocks with the prescribed padding at
* the end, and pass those blocks to the core SHA256 algorithm.
*/
#define BLKSIZE 64
void SHA256_Init(SHA256_State *s) {
SHA256_Core_Init(s);
s->blkused = 0;
s->lenhi = s->lenlo = 0;
}
void SHA256_Bytes(SHA256_State *s, const void *p, int len) {
unsigned char *q = (unsigned char *)p;
uint32 wordblock[16];
uint32 lenw = len;
int i;
/*
* Update the length field.
*/
s->lenlo += lenw;
s->lenhi += (s->lenlo < lenw);
if (s->blkused && s->blkused+len < BLKSIZE) {
/*
* Trivial case: just add to the block.
*/
memcpy(s->block + s->blkused, q, len);
s->blkused += len;
} else {
/*
* We must complete and process at least one block.
*/
while (s->blkused + len >= BLKSIZE) {
memcpy(s->block + s->blkused, q, BLKSIZE - s->blkused);
q += BLKSIZE - s->blkused;
len -= BLKSIZE - s->blkused;
/* Now process the block. Gather bytes big-endian into words */
for (i = 0; i < 16; i++) {
wordblock[i] =
( ((uint32)s->block[i*4+0]) << 24 ) |
( ((uint32)s->block[i*4+1]) << 16 ) |
( ((uint32)s->block[i*4+2]) << 8 ) |
( ((uint32)s->block[i*4+3]) << 0 );
}
SHA256_Block(s, wordblock);
s->blkused = 0;
}
memcpy(s->block, q, len);
s->blkused = len;
}
}
void SHA256_Final(SHA256_State *s, unsigned char *digest) {
int i;
int pad;
unsigned char c[64];
uint32 lenhi, lenlo;
if (s->blkused >= 56)
pad = 56 + 64 - s->blkused;
else
pad = 56 - s->blkused;
lenhi = (s->lenhi << 3) | (s->lenlo >> (32-3));
lenlo = (s->lenlo << 3);
memset(c, 0, pad);
c[0] = 0x80;
SHA256_Bytes(s, &c, pad);
c[0] = (lenhi >> 24) & 0xFF;
c[1] = (lenhi >> 16) & 0xFF;
c[2] = (lenhi >> 8) & 0xFF;
c[3] = (lenhi >> 0) & 0xFF;
c[4] = (lenlo >> 24) & 0xFF;
c[5] = (lenlo >> 16) & 0xFF;
c[6] = (lenlo >> 8) & 0xFF;
c[7] = (lenlo >> 0) & 0xFF;
SHA256_Bytes(s, &c, 8);
for (i = 0; i < 8; i++) {
digest[i*4+0] = (s->h[i] >> 24) & 0xFF;
digest[i*4+1] = (s->h[i] >> 16) & 0xFF;
digest[i*4+2] = (s->h[i] >> 8) & 0xFF;
digest[i*4+3] = (s->h[i] >> 0) & 0xFF;
}
}
void SHA256_Simple(const void *p, int len, unsigned char *output) {
SHA256_State s;
SHA256_Init(&s);
SHA256_Bytes(&s, p, len);
SHA256_Final(&s, output);
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(void) {
unsigned char digest[32];
int i, j, errors;
struct {
const char *teststring;
unsigned char digest[32];
} tests[] = {
{ "abc", {
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
} },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", {
0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
} },
};
errors = 0;
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
SHA256_Simple(tests[i].teststring,
strlen(tests[i].teststring), digest);
for (j = 0; j < 32; j++) {
if (digest[j] != tests[i].digest[j]) {
fprintf(stderr,
"\"%s\" digest byte %d should be 0x%02x, is 0x%02x\n",
tests[i].teststring, j, tests[i].digest[j], digest[j]);
errors++;
}
}
}
printf("%d errors\n", errors);
return 0;
}
#endif

22
cipher/sha256.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef _CIPHER_SHA256_H
#define _CIPHER_SHA256_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef unsigned int uint32;
typedef struct {
uint32 h[8];
unsigned char block[64];
int blkused;
uint32 lenhi, lenlo;
} SHA256_State;
void SHA256_Init(SHA256_State * s);
void SHA256_Bytes(SHA256_State * s, const void *p, int len);
void SHA256_Final(SHA256_State * s, unsigned char *output);
void SHA256_Simple(const void *p, int len, unsigned char *output);
void sha256_do_hmac(unsigned char* key, int keylen,
unsigned char *blk, int len, unsigned char *hmac);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_SHA256_H */

41
cipher/sha384.c Normal file
View File

@ -0,0 +1,41 @@
#include "sha384.h"
#define INIT(h,l) { h, l }
static void SHA384_Core_Init(SHA512_State *s) {
static const uint64 iv[] = {
INIT(0xcbbb9d5d, 0xc1059ed8), INIT(0x629a292a, 0x367cd507),
INIT(0x9159015a, 0x3070dd17), INIT(0x152fecd8, 0xf70e5939),
INIT(0x67332667, 0xffc00b31), INIT(0x8eb44a87, 0x68581511),
INIT(0xdb0c2e0d, 0x64f98fa7), INIT(0x47b5481d, 0xbefa4fa4),
};
int i;
for (i = 0; i < 8; i++)
s->h[i] = iv[i];
}
void SHA384_Init(SHA512_State *s) {
int i;
SHA384_Core_Init(s);
s->blkused = 0;
for (i = 0; i < 4; i++)
s->len[i] = 0;
}
void SHA384_Bytes(SHA512_State *s, const void *p, int len) {
SHA512_Bytes(s, p, len);
}
#define SHA384_DIGEST_SIZE 48
void SHA384_Final(SHA512_State *s, unsigned char *digest) {
SHA512_Final(s, digest);
digest[SHA384_DIGEST_SIZE] = 0x00;
}
void SHA384_Simple(const void *p, int len, unsigned char *output) {
SHA512_State s;
SHA384_Init(&s);
SHA384_Bytes(&s, p, len);
SHA384_Final(&s, output);
}

14
cipher/sha384.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _CIPHER_SHA384_H
#define _CIPHER_SHA384_H
#include "sha512.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void SHA384_Init(SHA512_State * s);
void SHA384_Bytes(SHA512_State * s, const void *p, int len);
void SHA384_Final(SHA512_State * s, unsigned char *output);
void SHA384_Simple(const void *p, int len, unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_SHA384_H */

364
cipher/sha512.c Normal file
View File

@ -0,0 +1,364 @@
/*
* SHA-512 algorithm as described at
*
* http://csrc.nist.gov/cryptval/shs.html
*/
#include <string.h>
#include "sha512.h"
//#define TEST
#define BLKSIZE 128
/*
* Arithmetic implementations. Note that AND, XOR and NOT can
* overlap destination with one source, but the others can't.
*/
#define add(r,x,y) ( r.lo = y.lo + x.lo, \
r.hi = y.hi + x.hi + ((uint32)r.lo < (uint32)y.lo) )
#define rorB(r,x,y) ( r.lo = ((uint32)x.hi >> ((y)-32)) | ((uint32)x.lo << (64-(y))), \
r.hi = ((uint32)x.lo >> ((y)-32)) | ((uint32)x.hi << (64-(y))) )
#define rorL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \
r.hi = ((uint32)x.hi >> (y)) | ((uint32)x.lo << (32-(y))) )
#define shrB(r,x,y) ( r.lo = (uint32)x.hi >> ((y)-32), r.hi = 0 )
#define shrL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \
r.hi = (uint32)x.hi >> (y) )
#define and(r,x,y) ( r.lo = x.lo & y.lo, r.hi = x.hi & y.hi )
#define xor(r,x,y) ( r.lo = x.lo ^ y.lo, r.hi = x.hi ^ y.hi )
#define not(r,x) ( r.lo = ~x.lo, r.hi = ~x.hi )
#define INIT(h,l) { h, l }
#define BUILD(r,h,l) ( r.hi = h, r.lo = l )
#define EXTRACT(h,l,r) ( h = r.hi, l = r.lo )
/* ----------------------------------------------------------------------
* Core SHA512 algorithm: processes 16-doubleword blocks into a
* message digest.
*/
#define Ch(r,t,x,y,z) ( not(t,x), and(r,t,z), and(t,x,y), xor(r,r,t) )
#define Maj(r,t,x,y,z) ( and(r,x,y), and(t,x,z), xor(r,r,t), \
and(t,y,z), xor(r,r,t) )
#define bigsigma0(r,t,x) ( rorL(r,x,28), rorB(t,x,34), xor(r,r,t), \
rorB(t,x,39), xor(r,r,t) )
#define bigsigma1(r,t,x) ( rorL(r,x,14), rorL(t,x,18), xor(r,r,t), \
rorB(t,x,41), xor(r,r,t) )
#define smallsigma0(r,t,x) ( rorL(r,x,1), rorL(t,x,8), xor(r,r,t), \
shrL(t,x,7), xor(r,r,t) )
#define smallsigma1(r,t,x) ( rorL(r,x,19), rorB(t,x,61), xor(r,r,t), \
shrL(t,x,6), xor(r,r,t) )
#define PUT_32BIT_MSB_FIRST(cp, value) ( \
(cp)[0] = (unsigned char)((value) >> 24), \
(cp)[1] = (unsigned char)((value) >> 16), \
(cp)[2] = (unsigned char)((value) >> 8), \
(cp)[3] = (unsigned char)(value))
static void SHA512_Core_Init(SHA512_State *s) {
static const uint64 iv[] = {
INIT(0x6a09e667, 0xf3bcc908),
INIT(0xbb67ae85, 0x84caa73b),
INIT(0x3c6ef372, 0xfe94f82b),
INIT(0xa54ff53a, 0x5f1d36f1),
INIT(0x510e527f, 0xade682d1),
INIT(0x9b05688c, 0x2b3e6c1f),
INIT(0x1f83d9ab, 0xfb41bd6b),
INIT(0x5be0cd19, 0x137e2179),
};
int i;
for (i = 0; i < 8; i++)
s->h[i] = iv[i];
}
static void SHA512_Block(SHA512_State *s, uint64 *block) {
uint64 w[80];
uint64 a,b,c,d,e,f,g,h;
static const uint64 k[] = {
INIT(0x428a2f98, 0xd728ae22), INIT(0x71374491, 0x23ef65cd),
INIT(0xb5c0fbcf, 0xec4d3b2f), INIT(0xe9b5dba5, 0x8189dbbc),
INIT(0x3956c25b, 0xf348b538), INIT(0x59f111f1, 0xb605d019),
INIT(0x923f82a4, 0xaf194f9b), INIT(0xab1c5ed5, 0xda6d8118),
INIT(0xd807aa98, 0xa3030242), INIT(0x12835b01, 0x45706fbe),
INIT(0x243185be, 0x4ee4b28c), INIT(0x550c7dc3, 0xd5ffb4e2),
INIT(0x72be5d74, 0xf27b896f), INIT(0x80deb1fe, 0x3b1696b1),
INIT(0x9bdc06a7, 0x25c71235), INIT(0xc19bf174, 0xcf692694),
INIT(0xe49b69c1, 0x9ef14ad2), INIT(0xefbe4786, 0x384f25e3),
INIT(0x0fc19dc6, 0x8b8cd5b5), INIT(0x240ca1cc, 0x77ac9c65),
INIT(0x2de92c6f, 0x592b0275), INIT(0x4a7484aa, 0x6ea6e483),
INIT(0x5cb0a9dc, 0xbd41fbd4), INIT(0x76f988da, 0x831153b5),
INIT(0x983e5152, 0xee66dfab), INIT(0xa831c66d, 0x2db43210),
INIT(0xb00327c8, 0x98fb213f), INIT(0xbf597fc7, 0xbeef0ee4),
INIT(0xc6e00bf3, 0x3da88fc2), INIT(0xd5a79147, 0x930aa725),
INIT(0x06ca6351, 0xe003826f), INIT(0x14292967, 0x0a0e6e70),
INIT(0x27b70a85, 0x46d22ffc), INIT(0x2e1b2138, 0x5c26c926),
INIT(0x4d2c6dfc, 0x5ac42aed), INIT(0x53380d13, 0x9d95b3df),
INIT(0x650a7354, 0x8baf63de), INIT(0x766a0abb, 0x3c77b2a8),
INIT(0x81c2c92e, 0x47edaee6), INIT(0x92722c85, 0x1482353b),
INIT(0xa2bfe8a1, 0x4cf10364), INIT(0xa81a664b, 0xbc423001),
INIT(0xc24b8b70, 0xd0f89791), INIT(0xc76c51a3, 0x0654be30),
INIT(0xd192e819, 0xd6ef5218), INIT(0xd6990624, 0x5565a910),
INIT(0xf40e3585, 0x5771202a), INIT(0x106aa070, 0x32bbd1b8),
INIT(0x19a4c116, 0xb8d2d0c8), INIT(0x1e376c08, 0x5141ab53),
INIT(0x2748774c, 0xdf8eeb99), INIT(0x34b0bcb5, 0xe19b48a8),
INIT(0x391c0cb3, 0xc5c95a63), INIT(0x4ed8aa4a, 0xe3418acb),
INIT(0x5b9cca4f, 0x7763e373), INIT(0x682e6ff3, 0xd6b2b8a3),
INIT(0x748f82ee, 0x5defb2fc), INIT(0x78a5636f, 0x43172f60),
INIT(0x84c87814, 0xa1f0ab72), INIT(0x8cc70208, 0x1a6439ec),
INIT(0x90befffa, 0x23631e28), INIT(0xa4506ceb, 0xde82bde9),
INIT(0xbef9a3f7, 0xb2c67915), INIT(0xc67178f2, 0xe372532b),
INIT(0xca273ece, 0xea26619c), INIT(0xd186b8c7, 0x21c0c207),
INIT(0xeada7dd6, 0xcde0eb1e), INIT(0xf57d4f7f, 0xee6ed178),
INIT(0x06f067aa, 0x72176fba), INIT(0x0a637dc5, 0xa2c898a6),
INIT(0x113f9804, 0xbef90dae), INIT(0x1b710b35, 0x131c471b),
INIT(0x28db77f5, 0x23047d84), INIT(0x32caab7b, 0x40c72493),
INIT(0x3c9ebe0a, 0x15c9bebc), INIT(0x431d67c4, 0x9c100d4c),
INIT(0x4cc5d4be, 0xcb3e42b6), INIT(0x597f299c, 0xfc657e2a),
INIT(0x5fcb6fab, 0x3ad6faec), INIT(0x6c44198c, 0x4a475817),
};
int t;
for (t = 0; t < 16; t++)
w[t] = block[t];
for (t = 16; t < 80; t++) {
uint64 p, q, r, tmp;
smallsigma1(p, tmp, w[t-2]);
smallsigma0(q, tmp, w[t-15]);
add(r, p, q);
add(p, r, w[t-7]);
add(w[t], p, w[t-16]);
}
a = s->h[0]; b = s->h[1]; c = s->h[2]; d = s->h[3];
e = s->h[4]; f = s->h[5]; g = s->h[6]; h = s->h[7];
for (t = 0; t < 80; t+=8) {
uint64 tmp, p, q, r;
#define ROUND(j,a,b,c,d,e,f,g,h) \
bigsigma1(p, tmp, e); \
Ch(q, tmp, e, f, g); \
add(r, p, q); \
add(p, r, k[j]) ; \
add(q, p, w[j]); \
add(r, q, h); \
bigsigma0(p, tmp, a); \
Maj(tmp, q, a, b, c); \
add(q, tmp, p); \
add(p, r, d); \
d = p; \
add(h, q, r);
ROUND(t+0, a,b,c,d,e,f,g,h);
ROUND(t+1, h,a,b,c,d,e,f,g);
ROUND(t+2, g,h,a,b,c,d,e,f);
ROUND(t+3, f,g,h,a,b,c,d,e);
ROUND(t+4, e,f,g,h,a,b,c,d);
ROUND(t+5, d,e,f,g,h,a,b,c);
ROUND(t+6, c,d,e,f,g,h,a,b);
ROUND(t+7, b,c,d,e,f,g,h,a);
}
{
uint64 tmp;
#define UPDATE(state, local) ( tmp = state, add(state, tmp, local) )
UPDATE(s->h[0], a); UPDATE(s->h[1], b);
UPDATE(s->h[2], c); UPDATE(s->h[3], d);
UPDATE(s->h[4], e); UPDATE(s->h[5], f);
UPDATE(s->h[6], g); UPDATE(s->h[7], h);
}
}
/* ----------------------------------------------------------------------
* Outer SHA512 algorithm: take an arbitrary length byte string,
* convert it into 16-doubleword blocks with the prescribed padding
* at the end, and pass those blocks to the core SHA512 algorithm.
*/
void SHA512_Init(SHA512_State *s) {
int i;
SHA512_Core_Init(s);
s->blkused = 0;
for (i = 0; i < 4; i++)
s->len[i] = 0;
}
void SHA512_Bytes(SHA512_State *s, const void *p, int len) {
unsigned char *q = (unsigned char *)p;
uint64 wordblock[16];
uint32 lenw = len;
int i;
/*
* Update the length field.
*/
for (i = 0; i < 4; i++) {
s->len[i] += lenw;
lenw = (s->len[i] < lenw);
}
if (s->blkused && s->blkused+len < BLKSIZE) {
/*
* Trivial case: just add to the block.
*/
memcpy(s->block + s->blkused, q, len);
s->blkused += len;
} else {
/*
* We must complete and process at least one block.
*/
while (s->blkused + len >= BLKSIZE) {
memcpy(s->block + s->blkused, q, BLKSIZE - s->blkused);
q += BLKSIZE - s->blkused;
len -= BLKSIZE - s->blkused;
/* Now process the block. Gather bytes big-endian into words */
for (i = 0; i < 16; i++) {
uint32 h, l;
h = ( ((uint32)s->block[i*8+0]) << 24 ) |
( ((uint32)s->block[i*8+1]) << 16 ) |
( ((uint32)s->block[i*8+2]) << 8 ) |
( ((uint32)s->block[i*8+3]) << 0 );
l = ( ((uint32)s->block[i*8+4]) << 24 ) |
( ((uint32)s->block[i*8+5]) << 16 ) |
( ((uint32)s->block[i*8+6]) << 8 ) |
( ((uint32)s->block[i*8+7]) << 0 );
BUILD(wordblock[i], h, l);
}
SHA512_Block(s, wordblock);
s->blkused = 0;
}
memcpy(s->block, q, len);
s->blkused = len;
}
}
void SHA512_Final(SHA512_State *s, unsigned char *digest) {
int i;
int pad;
unsigned char c[BLKSIZE];
uint32 len[4];
if (s->blkused >= BLKSIZE-16)
pad = (BLKSIZE-16) + BLKSIZE - s->blkused;
else
pad = (BLKSIZE-16) - s->blkused;
for (i = 4; i-- ;) {
uint32 lenhi = s->len[i];
uint32 lenlo = i > 0 ? s->len[i-1] : 0;
len[i] = (lenhi << 3) | (lenlo >> (32-3));
}
memset(c, 0, pad);
c[0] = 0x80;
SHA512_Bytes(s, &c, pad);
for (i = 0; i < 4; i++) {
c[i*4+0] = (len[3-i] >> 24) & 0xFF;
c[i*4+1] = (len[3-i] >> 16) & 0xFF;
c[i*4+2] = (len[3-i] >> 8) & 0xFF;
c[i*4+3] = (len[3-i] >> 0) & 0xFF;
}
SHA512_Bytes(s, &c, 16);
for (i = 0; i < 8; i++) {
uint32 h, l;
EXTRACT(h, l, s->h[i]);
digest[i*8+0] = (h >> 24) & 0xFF;
digest[i*8+1] = (h >> 16) & 0xFF;
digest[i*8+2] = (h >> 8) & 0xFF;
digest[i*8+3] = (h >> 0) & 0xFF;
digest[i*8+4] = (l >> 24) & 0xFF;
digest[i*8+5] = (l >> 16) & 0xFF;
digest[i*8+6] = (l >> 8) & 0xFF;
digest[i*8+7] = (l >> 0) & 0xFF;
}
}
void SHA512_Simple(const void *p, int len, unsigned char *output) {
SHA512_State s;
SHA512_Init(&s);
SHA512_Bytes(&s, p, len);
SHA512_Final(&s, output);
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(void) {
unsigned char digest[64];
int i, j, errors;
struct {
const char *teststring;
unsigned char digest512[64];
} tests[] = {
{ "abc", {
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
} },
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", {
0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
} },
{ NULL, {
0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64,
0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28,
0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a,
0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e,
0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b,
} },
};
errors = 0;
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
if (tests[i].teststring) {
SHA512_Simple(tests[i].teststring,
strlen(tests[i].teststring), digest);
} else {
SHA512_State s;
int n;
SHA512_Init(&s);
for (n = 0; n < 1000000 / 40; n++)
SHA512_Bytes(&s, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
40);
SHA512_Final(&s, digest);
}
for (j = 0; j < 64; j++) {
if (digest[j] != tests[i].digest512[j]) {
fprintf(stderr,
"\"%s\" digest512 byte %d should be 0x%02x, is 0x%02x\n",
tests[i].teststring, j, tests[i].digest512[j],
digest[j]);
errors++;
}
}
}
printf("%d errors\n", errors);
return 0;
}
#endif

23
cipher/sha512.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _CIPHER_SHA512_H
#define _CIPHER_SHA512_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct {
unsigned long hi, lo;
} uint64;
typedef unsigned int uint32;
typedef struct {
uint64 h[8];
unsigned char block[128];
int blkused;
uint32 len[4];
} SHA512_State;
void SHA512_Init(SHA512_State * s);
void SHA512_Bytes(SHA512_State * s, const void *p, int len);
void SHA512_Final(SHA512_State * s, unsigned char *output);
void SHA512_Simple(const void *p, int len, unsigned char *output);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_SHA512_H */

57
cipher/ssh.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef _CIPHER_SSHSSH_H_
#define _CIPHER_SSHSSH_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct ssh_mac {
void *(*make_context)(void);
void (*free_context)(void *);
void (*setkey) (void *, unsigned char *key);
/* whole-packet operations */
void (*generate) (void *, unsigned char *blk, int len, unsigned long seq);
int (*verify) (void *, unsigned char *blk, int len, unsigned long seq);
/* partial-packet operations */
void (*start) (void *);
void (*bytes) (void *, unsigned char *, int);
void (*genresult) (void *, unsigned char *);
int (*verresult) (void *, unsigned char *);
char *name;
int len;
char *text_name;
};
struct ssh_hash {
void *(*init)(void); /* also allocates context */
void (*bytes)(void *, void *, int);
void (*final)(void *, unsigned char *); /* also frees context */
int hlen; /* output length in bytes */
char *text_name;
};
struct ssh2_cipher {
void *(*make_context)(void);
void (*free_context)(void *);
void (*setiv) (void *, unsigned char *key); /* for SSH-2 */
void (*setkey) (void *, unsigned char *key);/* for SSH-2 */
void (*encrypt) (void *, unsigned char *blk, int len);
void (*decrypt) (void *, unsigned char *blk, int len);
char *name;
int blksize;
int keylen;
unsigned int flags;
#define SSH_CIPHER_IS_CBC 1
char *text_name;
};
extern const struct ssh_mac ssh_hmac_md5;
extern const struct ssh_mac ssh_hmac_sha1;
extern const struct ssh_mac ssh_hmac_sha1_buggy;
extern const struct ssh_mac ssh_hmac_sha1_96;
extern const struct ssh_mac ssh_hmac_sha1_96_buggy;
extern const struct ssh_mac ssh_hmac_sha256;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CIPHER_SSHSSH_H_ */

1246
cipher/tdes.c Normal file

File diff suppressed because it is too large Load Diff

18
cipher/tdes.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef _T_DES_H
#define _T_DES_H
#define MAX_CI_LEN 1024
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int cipher2(const char* key,char* plain_text,char* crypted_text,int length);
int decipher2(const char* key,char* plain_text,char* crypted_text,int length);
int cipher3(const char* key,char* plain_text,char* crypted_text,int length);
int decipher3(const char* key,char* plain_text,char* crypted_text,int length);
void TDes(char orientation,char *PlainText,char *key, char *ucEncipher);
char asc_bcd(char *what);
void tohex(const char* ins, char* outs, int len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _T_DES_H */

39
cipher/unittest/Makefile Normal file
View File

@ -0,0 +1,39 @@
include ../../Makefile.comm
PROJECT = unittest
SRCS = .
SRCS += ./ut
SRCS += ..
SRCS += ../../base
LIB = -lstdc++ -lpthread
INC = -I.
INC += -I..
INC += -I../../base
CPP_SRCS = $(foreach d,$(SRCS),$(wildcard $(d)/*.cpp))
C_SRCS = $(foreach d,$(SRCS),$(wildcard $(d)/*.c))
CPP_OBJS = $(patsubst %.cpp, %.o, $(CPP_SRCS))
C_OBJS = $(patsubst %.c, %.o, $(C_SRCS))
OBJS = $(CPP_OBJS)
OBJS += $(C_OBJS)
all : $(PROJECT)
$(PROJECT) : $(OBJS) $(MODULE)
$(CC) -o $@ $(OBJS) $(LIB)
@echo ""
@echo "+--------------------------------------------+"
@echo "| Finish compilation unittest |"
@echo "+--------------------------------------------+"
@echo "| copyright(c)Wang Yaofu voipman@qq.com |"
@echo "+--------------------------------------------+"
clean:
rm -rf *.o *.a *_unittest
install :
test -d ../test || mkdir -p ../test
cp unittest ../test

View File

@ -0,0 +1,380 @@
/*
** Copyright (C) 2014 Wang Yaofu
** All rights reserved.
**
**Author:Wang Yaofu voipman@qq.com
**Description: The unit test file of base64.
*/
#include <string.h>
#include <stdlib.h>
#include "base/base64.h"
#include "cipher/md5.h"
#include "cipher/digest.h"
#include "cipher/sha1.h"
#include "cipher/sha.h"
#include "cipher/sha256.h"
#include "cipher/sha512.h"
#include "cipher/sha224.h"
#include "cipher/sha384.h"
#include "cipher/hmac.h"
#include "cipher/tdes.h"
#include "cipher/rc4.h"
#include "cipher/pbkdf2_hmac.h"
#include "base/stringutils.h"
#include "ut/test_harness.h"
using namespace std;
using namespace common;
void EncodeAndDecode(const std::string& s)
{
string b;
EXPECT_TRUE(Base64Encode(s, &b));
string c;
EXPECT_TRUE(Base64Decode(b, &c));
EXPECT_EQ(c, s);
}
TEST(Base64Test, BasicTest)
{
EncodeAndDecode("a");
EncodeAndDecode("ab");
EncodeAndDecode("abc");
EncodeAndDecode("abcd");
EncodeAndDecode("abcde");
EncodeAndDecode("abcdef");
EncodeAndDecode("abcdefg");
}
TEST(Base64Test, EncodeEmptyBuffer)
{
std::string output;
EXPECT_TRUE(Base64Encode("", &output));
}
TEST(Base64Test, DecodeEmptyString)
{
std::string output;
EXPECT_TRUE(Base64Decode("", &output));
}
TEST(Base64Test, DecodeWithPadding)
{
std::string output;
std::string s = "e===";
EXPECT_TRUE(!Base64Decode(s, &output));
s = "";
EXPECT_TRUE(Base64Decode(s, &output));
s = "abcdAFCD\r\neF==";
EXPECT_TRUE(Base64Decode(s, &output));
EXPECT_EQ((size_t)7, output.size());
s = "abcdAFCD\r\neF==\r\n\r\n";
EXPECT_TRUE(Base64Decode(s, &output));
EXPECT_EQ((size_t)7, output.size());
s = "abcdAFCD\r\neF=a";
EXPECT_TRUE(!Base64Decode(s, &output));
s = "abcdAFCD\r\ne===";
EXPECT_TRUE(!Base64Decode(s, &output));
s = "abcdAFFCD\r\ne==";
EXPECT_TRUE(Base64Decode(s, &output));
EXPECT_EQ((size_t)7, output.size());
s = "abcdAFFCD\r\ne=\r\n=";
EXPECT_TRUE(Base64Decode(s, &output));
EXPECT_EQ((size_t)7, output.size());
s = "abcdAF=D\r\nef==";
EXPECT_TRUE(!Base64Decode(s, &output));
s = "abcdA";
EXPECT_TRUE(!Base64Decode(s, &output));
Base64Encode("admin:123", &output);
EXPECT_EQ(string("YWRtaW46MTIz"), output);
Base64Decode(output, &s);
EXPECT_EQ(string("admin:123"), s);
}
TEST(Md5Test, BasicTest) {
unsigned char input[] = "1234567890";
unsigned char output[100] = {0};
MD5Calc(input, 10, output);
std::string cryptOut = "e807f1fcf82d132f9bb018ca6738a19f";
std::string calcOut = StrUtils::Hex((char *)output, 16);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha1Test, BasicTest) {
unsigned char input[] = "1234567687890";
unsigned char output[100] = {0};
//SHA1Calc(input, 13, output);
SHA_Simple(input, 13, output);
std::string cryptOut = "21885c92cf31020ba246bfaa999e7c8e508c8d53";
std::string calcOut = StrUtils::Hex((char *)output, 20);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha256Test, BasicTest1)
{
unsigned char input[] = "abc";
unsigned char output[33] = {0};
SHA256_Simple(input, 3, output);
std::string cryptOut = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
std::string calcOut = StrUtils::Hex((char *)output, 32);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha256Test, BasicTest2)
{
unsigned char input[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
unsigned char output[65] = {0};
SHA256_Simple(input, 56, output);
std::string cryptOut = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
std::string calcOut = StrUtils::Hex((char *)output, 32);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha224Test, BasicTest1)
{
unsigned char input[] = "abc";
unsigned char output[33] = { 0 };
SHA224_Simple(input, 3, output);
std::string cryptOut = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
std::string calcOut = StrUtils::Hex((char *)output, 28);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha384Test, BasicTest1)
{
unsigned char input[] = "abc";
unsigned char output[65] = { 0 };
SHA384_Simple(input, 3, output);
std::string cryptOut = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
std::string calcOut = StrUtils::Hex((char *)output, 48);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha512Test, BasicTest1)
{
unsigned char input[] = "abc";
unsigned char output[65] = {0};
SHA512_Simple(input, 3, output);
std::string cryptOut = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
std::string calcOut = StrUtils::Hex((char *)output, 64);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha512Test, BasicTest2)
{
unsigned char input[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
unsigned char output[65] = {0};
SHA512_Simple(input, 112, output);
std::string cryptOut = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909";
std::string calcOut = StrUtils::Hex((char *)output, 64);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(Sha512Test, BasicTest3)
{
unsigned char input[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
unsigned char output[65] = {0};
SHA512_State s;
int n;
SHA512_Init(&s);
for (n = 0; n < 1000000 / 40; n++)
SHA512_Bytes(&s, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 40);
SHA512_Final(&s, output);
std::string cryptOut = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b";
std::string calcOut = StrUtils::Hex((char *)output, 64);
EXPECT_EQ(cryptOut, calcOut);
}
TEST(TdesTest, BasicTest) {
char key[16]={"key"};
char encpt[100];
char result[100];
char plain[] = "1234567890";
int len = strlen(plain);
cipher2(key, plain, encpt, len);
decipher2(key, result, encpt, strlen(encpt));
EXPECT_EQ(std::string(plain), std::string(result));
cipher3(key, plain, encpt,len);
decipher3(key, result, encpt, strlen(encpt));
EXPECT_EQ(std::string(plain), std::string(result));
}
TEST(TDigestTest, BasicTest) {
unsigned char * pszNonce = (unsigned char*)"xx";
unsigned char * pszCNonce = (unsigned char*)"248a286a6dda379e";
unsigned char * pszUser = (unsigned char*)"admin";
unsigned char * pszRealm = (unsigned char*)"xx";
unsigned char * pszPass = (unsigned char*)"123456";
unsigned char * pszAlg = (unsigned char*)"md5";
unsigned char * szNonceCount = (unsigned char*)"00000001";
unsigned char * pszMethod = (unsigned char*)"GET";
unsigned char * pszQop = (unsigned char*)"auth";
unsigned char * pszURI = (unsigned char*)"/fs/v1/addsite";
HASHHEX HA1;
HASHHEX HA2 = "";
HASHHEX Response;
DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce, pszCNonce, HA1);
DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,
pszMethod, pszURI, HA2, Response);
string ha1((char *)HA1);
string digest((char *)Response);
EXPECT_EQ(string("ec6d21cdfe89d1a6b0be59a8f65a004f"), ha1);
EXPECT_EQ(string("02233a6d3420e580bf416cd340c43590"), digest);
}
TEST(RC4_Test, BasicTest) {
unsigned char* key = (unsigned char*)"key";
char blk[100] = {0};
strcpy(blk, "The quick brown fox jumps over the lazy dog");
RC4_Sample(key, 3, (unsigned char*)blk, 43);
string hexBlk = StrUtils::Hex(blk, 43);
EXPECT_EQ(string("5f0451cd55fa1229236b6a09792a7cdde91b9546c1948e8f45d3c7cb5c9e5bea7c5896e2c8f5c39c57b898"), hexBlk);
RC4_Sample(key, 3, (unsigned char*)blk, 43);
EXPECT_EQ(string("The quick brown fox jumps over the lazy dog"), string(blk));
}
TEST(PKCS5_PBKDF2_HMAC_Test, BasicTest) {
unsigned char* key = (unsigned char*)"key";
char blk[100] = { 0 };
strcpy(blk, "The quick brown fox jumps over the lazy dog");
char hmac[21] = { 0 };
PKCS5_PBKDF2_HMAC((unsigned char*)blk, 43, key, 3, 10, 20, (unsigned char*)hmac);
string hexBlk = StrUtils::Hex(hmac, 20);
EXPECT_EQ(string("2ca6b06c1ed5599af0546fc0067d1712e236b1de"), hexBlk);
}
TEST(PKCS5_PBKDF2_HMAC_Test, BasicTest1) {
unsigned char* key = (unsigned char*)"salt";
char blk[100] = { 0 };
strcpy(blk, "password");
char hmac[21] = { 0 };
PKCS5_PBKDF2_HMAC((unsigned char*)blk, 8, key, 4, 2, 20, (unsigned char*)hmac);
string hexBlk = StrUtils::Hex(hmac, 20);
EXPECT_EQ(string("ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"), hexBlk);
}
TEST(PKCS5_PBKDF2_HMAC_Test, BasicTestSha256_1) {
unsigned char* key = (unsigned char*)"salt";
char blk[100] = { 0 };
strcpy(blk, "password");
char hmac[33] = { 0 };
PKCS5_PBKDF2_HMAC2((unsigned char*)blk, 8, key, 4, 2, 32, (unsigned char*)hmac);
string hexBlk = StrUtils::Hex(hmac, 32);
EXPECT_EQ(string("ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43"), hexBlk);
}
TEST(PKCS5_PBKDF2_HMAC_Test, BasicTestSha256_2) {
unsigned char* key = (unsigned char*)"salt";
char blk[100] = { 0 };
strcpy(blk, "password");
char hmac[33] = { 0 };
PKCS5_PBKDF2_HMAC2((unsigned char*)blk, 8, key, 4, 1, 32, (unsigned char*)hmac);
string hexBlk = StrUtils::Hex(hmac, 32);
EXPECT_EQ(string("120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b"), hexBlk);
}
TEST(PKCS5_PBKDF2_HMAC_Test, BasicTestSha512_2) {
unsigned char* key = (unsigned char*)"salt";
char blk[100] = { 0 };
strcpy(blk, "password");
char hmac[65] = { 0 };
PKCS5_PBKDF2_HMAC2((unsigned char*)blk, 8, key, 4, 1, 64, (unsigned char*)hmac);
string hexBlk = StrUtils::Hex(hmac, 64);
EXPECT_EQ(string("120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b4dbf3a2f3dad3377264bb7b8e8330d4efc7451418617dabef683735361cdc18c"), hexBlk);
}
TEST(md5_hmac, BasicTest) {
unsigned char* key = (unsigned char*)"key";
unsigned char* blk = (unsigned char*)"The quick brown fox jumps over the lazy dog";
char hmac[21] = {0};
hmac_md5(key, 3, blk, 43, (unsigned char*)hmac);
string actualHmac = StrUtils::Hex(hmac, 16);
EXPECT_EQ(string("80070713463e7749b90c2dc24911e275"), actualHmac);
memset(hmac, 0, sizeof hmac);
hmac_md5(key, 0, blk, 0, (unsigned char*)hmac);
actualHmac = StrUtils::Hex(hmac, 16);
EXPECT_EQ(string("74e6f7298a9c2d168935f58c001bad88"), actualHmac);
}
TEST(sha1_hmac, BasicTest) {
unsigned char* key = (unsigned char*)"key";
unsigned char* blk = (unsigned char*)"wangyaofu try sha256 hash.";
char hmac[21] = { 0 };
hmac_sha1(key, 3, blk, 26, (unsigned char*)hmac);
string actualHmac = StrUtils::Hex(hmac, 20);
EXPECT_EQ(string("5e3c90f7bcbbe8c4ae878d7a6b186c112f005714"), actualHmac);
memset(hmac, 0, sizeof hmac);
hmac_sha1(key, 0, blk, 26, (unsigned char*)hmac);
actualHmac = StrUtils::Hex(hmac, 20);
EXPECT_EQ(string("df50dee5e03d275d9fcfc024893e1dc94e464a8c"), actualHmac);
}
TEST(sha224_hmac, BasicTest) {
unsigned char* key = (unsigned char*)"key";
unsigned char* blk = (unsigned char*)"wangyaofu try sha224 hash.";
char hmac[33] = { 0 };
hmac_sha224(key, 3, blk, 26, (unsigned char*)hmac);
string actualHmac = StrUtils::Hex(hmac, 28);
EXPECT_EQ(string("4d5a9a6ed549145dfbc30b0752ae3e05e06ccdd5695ec980f5a5739e"), actualHmac);
memset(hmac, 0, sizeof hmac);
hmac_sha224(key, 0, blk, 26, (unsigned char*)hmac);
actualHmac = StrUtils::Hex(hmac, 28);
EXPECT_EQ(string("91a5e2e9d550a8bdd82c1e59bb149655fc6d34d90d8a29ce77a391d2"), actualHmac);
}
TEST(sha256_hmac, BasicTest) {
unsigned char* key = (unsigned char*)"key";
unsigned char* blk = (unsigned char*)"wangyaofu try sha256 hash.";
char hmac[33] = { 0 };
hmac_sha256(key, 3, blk, 26, (unsigned char*)hmac);
string actualHmac = StrUtils::Hex(hmac, 32);
EXPECT_EQ(string("dc1099cd35452f3cf1f6c11d3884bc4c9b637523c4e74060e1332eac01e7ad8e"), actualHmac);
memset(hmac, 0, sizeof hmac);
hmac_sha256(key, 0, blk, 26, (unsigned char*)hmac);
actualHmac = StrUtils::Hex(hmac, 32);
EXPECT_EQ(string("37df81f1f26bb3949d4aad5ee27bb8bc5f124a7ff4d46e6d572ed96d5bde0ed8"), actualHmac);
}
TEST(sha512_hmac, BasicTest) {
unsigned char* key = (unsigned char*)"key";
unsigned char* blk = (unsigned char*)"37df81f1f26bb3949d4aad5ee27bb8bc5f124a7ff4d46e6d572ed96d5bde0ed8";
char hmac[65] = { 0 };
hmac_sha512(key, 3, blk, 64, (unsigned char*)hmac);
string actualHmac = StrUtils::Hex(hmac, 64);
EXPECT_EQ(string("f671db32ad7cc79121e432bd05f2e1a3ecf2f450c73b839584feb0371a4c05d018222a59fea6077e3681dc27322e1f389a35118f0e23188d7d4ca10741ee7746"), actualHmac);
memset(hmac, 0, sizeof hmac);
hmac_sha512(key, 0, blk, 64, (unsigned char*)hmac);
actualHmac = StrUtils::Hex(hmac, 64);
EXPECT_EQ(string("ac7b05b5c77842d7d8697bd0bb19ee74952f291b5dff9b2a2e58d82192368576dc81277ab3d59c0bc5a8fec61470ca1d8e3766f873d9769290be7c4cc855f32f"), actualHmac);
}

View File

@ -0,0 +1,95 @@
#include "test_harness.h"
#include <string>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <vector>
namespace common {
namespace test {
int errCount = 0;
namespace {
struct Test {
const char* base;
const char* name;
void(*func)();
};
std::vector<Test>* tests;
}
bool RegisterTest(const char* base, const char* name, void(*func)()) {
if (tests == NULL) {
tests = new std::vector<Test>;
}
Test t;
t.base = base;
t.name = name;
t.func = func;
tests->push_back(t);
return true;
}
int RunAllTests(const char* matcher) {
int num = 0;
if (tests != NULL) {
for (size_t i = 0; i < tests->size(); i++) {
const Test& t = (*tests)[i];
if (matcher != NULL) {
std::string name = t.base;
name.push_back('.');
name.append(t.name);
if (strstr(name.c_str(), matcher) == NULL) {
continue;
}
}
fprintf(stderr, "\033[0;32m[ RUN ] ==== Test %s.%s\n", t.base, t.name);
fprintf(stderr, "\033[0m");
(*t.func)();
++num;
}
}
fprintf(stderr, "\033[0;32m[ PASS ] ==== PASSED %d tests\n", num);
fprintf(stderr, "\033[0;31m[ NOPASS ] ==== ERROR %d tests\n", errCount);
fprintf(stderr, "\033[0m\n");
return 0;
}
std::string TmpDir() {
return "/tmp";
}
int RandomSeed() {
return 301;
}
TestPerfomence::TestPerfomence() {
startMs_ = NowMs();
}
TestPerfomence::TestPerfomence(int size) {
startMs_ = NowMs();
fprintf(stderr,
"\033[0;32m[ RUN ] ==== start to run %lu cases.\n",
size);
}
TestPerfomence::~TestPerfomence() {
long endMs = NowMs();
fprintf(stderr,
"\033[0;32m[ RUN ] ==== start at %lu, stop at %lu, cost:[%lu]\n",
startMs_, endMs, endMs - startMs_);
}
long TestPerfomence::NowMs() {
struct timeval timeNow;
gettimeofday(&timeNow, NULL);
return (timeNow.tv_sec) * 1000 + timeNow.tv_usec / 1000;
}
}
} // namespace common
using namespace common::test;
int main(int argc, char** argv) {
common::test::RunAllTests(NULL);
return 0;
}

View File

@ -0,0 +1,152 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
namespace common {
namespace test {
extern int errCount;
// Run some of the tests registered by the TEST() macro. If the
// environment variable "LEVELDB_TESTS" is not set, runs all tests.
// Otherwise, runs only the tests whose name contains the value of
// "LEVELDB_TESTS" as a substring. E.g., suppose the tests are:
// TEST(Foo, Hello) { ... }
// TEST(Foo, World) { ... }
// LEVELDB_TESTS=Hello will run the first test
// LEVELDB_TESTS=o will run both tests
// LEVELDB_TESTS=Junk will run no tests
//
// Returns 0 if all tests pass.
// Dies or returns a non-zero value if some test fails.
extern int RunAllTests(const char* matcher);
// Return the directory to use for temporary storage.
extern std::string TmpDir();
// Return a randomization seed for this run. Typically returns the
// same number on repeated invocations of this binary, but automated
// runs may be able to vary the seed.
extern int RandomSeed();
// An instance of Tester is allocated to hold temporary state during
// the execution of an assertion.
class Tester {
private:
bool ok_;
const char* fname_;
int line_;
std::stringstream ss_;
public:
Tester(const char* f, int l)
: ok_(true), fname_(f), line_(l) {
}
~Tester() {
if (!ok_) {
fprintf(stderr, "\033[0;31m[ ERROR ] ==== %s:%d:%s\n",
fname_, line_, ss_.str().c_str());
fprintf(stderr, "\033[0m");
errCount++;
//exit(1);
}
}
Tester& Is(bool b, const char* msg) {
if (!b) {
ss_ << " Assertion failure " << msg;
ok_ = false;
}
return *this;
}
#define BINARY_OP(name,op) \
template <class X, class Y> \
Tester& name(const X& x, const Y& y) { \
if (! (x op y)) { \
ss_ << " failed: Expect:" << x << (" " #op " ") << "Actual:" << y; \
ok_ = false; \
} \
return *this; \
}
BINARY_OP(IsEq, ==)
BINARY_OP(IsNe, !=)
BINARY_OP(IsGe, >=)
BINARY_OP(IsGt, >)
BINARY_OP(IsLe, <=)
BINARY_OP(IsLt, <)
#undef BINARY_OP
#define DOUBLE_OP(name,op) \
template <class X, class Y> \
Tester& name(const X& x, const Y& y) { \
if (! (x - y > -0.000001 && x-y <0.000001)) { \
ss_ << " failed: Expect:" << x << (" " #op " ") << "Actual:" << y; \
ok_ = false; \
} \
return *this; \
}
DOUBLE_OP(IsDoubleEq, ==)
#undef DOUBLE_OP
// Attach the specified value to the error message if an error has occurred
template <class V>
Tester& operator<<(const V& value) {
if (!ok_) {
ss_ << " " << value;
}
return *this;
}
};
#define ASSERT_TRUE(c) ::common::test::Tester(__FILE__, __LINE__).Is((c), #c)
#define ASSERT_FALSE(c) ::common::test::Tester(__FILE__, __LINE__).Is(!(c), #c)
#define ASSERT_EQ(a,b) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(b))
#define ASSERT_NE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsNe((a),(b))
#define ASSERT_GE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsGe((a),(b))
#define ASSERT_GT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsGt((a),(b))
#define ASSERT_LE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLe((a),(b))
#define ASSERT_LT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLt((a),(b))
#define EXPECT_GT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLt((a),(b))
#define EXPECT_LT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLt((a),(b))
#define EXPECT_EQ(a,b) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(b))
#define EXPECT_NE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsNe((a),(b))
#define EXPECT_DOUBLE_EQ(a,b) ::common::test::Tester(__FILE__, __LINE__).IsDoubleEq((a),(b))
#define EXPECT_TRUE(a) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(true))
#define EXPECT_FALSE(a) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(false))
#define EXPECT_THROW(a,exceptions) try {a;} catch(exceptions e) {EXPECT_TRUE(true);} catch(...) {EXPECT_TRUE(false);}
#define EXPECT_ANY_THROW(a) try {a;} catch(...) {EXPECT_TRUE(true);}
#define TCONCAT(a,b) TCONCAT1(a,b)
#define TCONCAT1(a,b) a##b
#define TEST(base,name) \
class TCONCAT(_Test_,base##name) : public ::common::test::TestBase { \
public: \
void _Run(); \
static void _RunIt() { \
TCONCAT(_Test_,base##name) t; \
t._Run(); \
} \
}; \
bool TCONCAT(_Test_ignored_,base##name) = \
::common::test::RegisterTest(#base, #name, &TCONCAT(_Test_,base##name)::_RunIt); \
void TCONCAT(_Test_,base##name)::_Run()
// Register the specified test. Typically not used directly, but
// invoked via the macro expansion of TEST.
extern bool RegisterTest(const char* base, const char* name, void (*func)());
class TestBase {};
class TestPerfomence {
public:
TestPerfomence();
TestPerfomence(int size);
~TestPerfomence();
long NowMs();
private:
long startMs_;
};
#define TEST_PERF(a,size) ::common::test::TestPerfomence a(size);
} // namespace test
} // namespace common