Skip to content

Commit

Permalink
made password hashing function work by only doing 16bit operations
Browse files Browse the repository at this point in the history
  • Loading branch information
iamcal authored and felixge committed Sep 2, 2010
1 parent 4cc30d3 commit 7c06248
Showing 1 changed file with 109 additions and 20 deletions.
129 changes: 109 additions & 20 deletions lib/mysql/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,113 @@ exports.token = function(password, scramble) {
// This is a port of sql/password.c:hash_password which needs to be used for
// pre-4.1 passwords.
exports.hashPassword = function(password) {
var nr = 1345345333,
add = 7,
nr2 = 0x12345671,
result = new Buffer(8);

password = new Buffer(password);
for (var i = 0; i < password.length; i++) {
var c = password[i];
if (c == 32 || c == 9) {
// skip space in password
continue;
}

nr ^= this.multiply(((nr & 63) + add), c) + (nr << 8);
nr2 += (nr2 << 8) ^ nr;
add += c;
}

this.int32Write(result, nr & ((1 << 31) - 1), 0);
this.int32Write(result, nr2 & ((1 << 31) - 1), 4);
var nr = [0x5030, 0x5735];
var add = 7;
var nr2 = [0x1234, 0x5671];
var result = new Buffer(8);

return result;
password = new Buffer(password);
for (var i = 0; i < password.length; i++) {
var c = password[i];
if (c == 32 || c == 9) {
// skip space in password
continue;
}

// nr^= (((nr & 63)+add)*c)+ (nr << 8);
// nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8)))
nr = this.xor32(
nr,
this.add32(
this.mul32(
this.add32(
this.and32(nr, [0,63]),
[0,add]
),
[0,c]
),
this.shl32(nr, 8)
)
);

// nr2+=(nr2 << 8) ^ nr;
// nr2 = add(nr2, xor(shl(nr2, 8), nr))
nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr));

// add+=tmp;
add += c;
}

this.int32Write2(result, nr, 0);
this.int32Write2(result, nr2, 4);

return result;
}

exports.fmt32 = function(x){
var a = x[0].toString(16);
var b = x[1].toString(16);

if (a.length == 1) a = "000"+a;
if (a.length == 2) a = "00"+a;
if (a.length == 3) a = "0"+a;
if (b.length == 1) b = "000"+b;
if (b.length == 2) b = "00"+b;
if (b.length == 3) b = "0"+b;
return "" + a + '/' + b;
}

exports.xor32 = function(a,b){
return [a[0] ^ b[0], a[1] ^ b[1]];
}

exports.add32 = function(a,b){

var low = a[1] + b[1];
var rem = (low & 0xFFFF0000) >> 16;
var high = a[0] + b[0] + rem;

return [high & 0xFFFF, low & 0xFFFF];
}

exports.mul32 = function(a,b){

var x = a[1] * b[1];
var y = a[0] * b[1];
var z = a[1] * b[0];
var w = a[0] * b[0];

var col1 = x & 0xFFFF;
var col2 = ((x >> 16) & 0xFFFF) + (y & 0xFFFF) + (z & 0xFFFF);
var col3 = ((y >> 16) & 0xFFFF) + ((z >> 16) & 0xFFFF) + (w & 0xFFFF);
var col4 = ((w >> 16) & 0xFFFF);

var w1 = col1;
var w2 = col2 & 0xFFFF;
var col2_over = ((col2 >> 16) & 0xFFFF);
var w3 = (col3 + col2_over) & 0xFFFF;
var col3_over = ((w3 >> 16) & 0xFFFF);
var w4 = (col4 + col3_over) & 0xFFFF;

return [w2, w1];
}

exports.and32 = function(a,b){
return [a[0] & b[0], a[1] & b[1]]
}

exports.shl32 = function(a,b){
// assume b is 16 or less
var low = a[1] << b;
var rem = (low & 0xFFFF0000) >> 16;
var high = (a[0] << b) | rem;

return [high & 0xFFFF, low & 0xFFFF];
}



// Provided by Herbert Vojčík, needed to deal with float point precision problems in JS
exports.multiply = function(a, b) {
var a1 = a >>> 16,
Expand All @@ -78,3 +161,9 @@ exports.int32Write = function(buffer, number, offset) {
buffer[offset + 3] = Math.floor(unsigned);
};

exports.int32Write2 = function(buffer, number, offset) {
buffer[offset] = (number[0] >> 8) & 0x7F;
buffer[offset+1] = (number[0]) & 0xFF;
buffer[offset+2] = (number[1] >> 8) & 0xFF;
buffer[offset+3] = (number[1]) & 0xFF;
};

0 comments on commit 7c06248

Please sign in to comment.