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