cipher for sha1/sha256/sha224/sha512/sha384 md5 hmac aes 3des pbkdf2 rsa digest.
This commit is contained in:
parent
baaef1e534
commit
061d2cf317
|
@ -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 $@
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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);
|
||||
};
|
|
@ -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_ */
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
||||
*/
|
|
@ -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_
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
@ -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_ */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue