winamp/Src/Plugins/DSP/dsp_sc/sc2srclib/uvAuth21/uvAuth21.cpp
2024-09-24 14:54:57 +02:00

90 lines
2.8 KiB
C++

#include "uvAuth21.h"
uvAuth21::uvAuth21(void) {
}
uvAuth21::~uvAuth21(void) {
}
string uvAuth21::encrypt(string user,string pass,string key) {
string blob;
uint8_t* username = (uint8_t*)user.data();
uint8_t* password = (uint8_t*)pass.data();
uint8_t* cipherkey = (uint8_t*)key.data();
blob = XTEA_encipher(username,user.length(),cipherkey,key.length());
blob += ':';
blob += XTEA_encipher(password,pass.length(),cipherkey,key.length());
return blob;
}
const char * uvAuth21::encrypt(char * user,char * pass,char * key) {
static string blob;
uint8_t* username = (uint8_t*)user;
uint8_t* password = (uint8_t*)pass;
uint8_t* cipherkey = (uint8_t*)key;
blob = XTEA_encipher(username,sizeof(user),cipherkey,sizeof(key));
blob += ':';
blob += XTEA_encipher(password,sizeof(pass),cipherkey,sizeof(key));
return blob.c_str();
}
// from wikipedia. Slightly modified to be 32/64 bit clean
void uvAuth21::XTEA_encipher(__uint32* v, __uint32* k) {
unsigned int num_rounds = 32;
__uint32 v0=v[0], v1=v[1], i;
__uint32 sum=0, delta=0x9E3779B9;
for(i=0; i<num_rounds; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}
__uint32 uvAuth21::fourCharsToLong(__uint8 *s) {
__uint32 l = 0;
l |= s[0]; l <<= 8;
l |= s[1]; l <<= 8;
l |= s[2]; l <<= 8;
l |= s[3];
return l;
}
std::vector<std::string> &uvAuth21::split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> uvAuth21::dosplit(const std::string &s, char delim) {
std::vector<std::string> elems;
return split(s, delim, elems);
}
std::string uvAuth21::XTEA_encipher(const __uint8* c_data,size_t c_data_cnt, const __uint8* c_key,size_t c_key_cnt) {
std::ostringstream oss;
std::vector<__uint8> key(c_key,c_key + c_key_cnt);
std::vector<__uint8> data(c_data,c_data + c_data_cnt);
// key is always 128 bits
while(key.size() < 16) key.push_back(XTEA_KEY_PAD); // pad key with zero
__uint32 k[4] = { fourCharsToLong(&key[0]),fourCharsToLong(&key[4]),fourCharsToLong(&key[8]),fourCharsToLong(&key[12])};
// data is multiple of 64 bits
size_t siz = data.size();
while(siz % 8) { siz+=1; data.push_back(XTEA_DATA_PAD);} // pad data with zero
for(size_t x = 0; x < siz; x+=8) {
__uint32 v[2];
v[0] = fourCharsToLong(&data[x]);
v[1] = fourCharsToLong(&data[x+4]);
XTEA_encipher(v,k);
oss << setw(8) << setfill('0') << hex << v[0];
oss << setw(8) << setfill('0') << hex << v[1]; // hex values. uvox uses colon as seperator so we can't use chars for
// fear of collision
}
return oss.str();
}