I am trying to build a Objective-C client for KeyBase.io. Some of the String specifics are getting the best of me however.
Consider this pseudocode from the Keybase api docs:
pwh = scrypt(passphrase, hex2bin(salt), N=215, r=8, p=1, dkLen=224)[192:224]
I believe that a half correct Objective-C mapping would be (scrypt function from Tarsnap and helper category) :
uint8_t *passphrase = (uint8_t *)[@"AVeryCleverPassword1" dataUsingEncoding:NSASCIIStringEncoding].bytes;
uint8_t *salt = (uint8_t *)@"32355c2e7843513463263...".decodeFromHexidecimal.bytes;
uint8_t buffer[224];
crypto_scrypt(passphrase, 20, salt, 24, pow(2, 15), 8, 1, buffer, 224);
uint8_t *pwh = buffer + 192;
The buffer looks like this which doesn't make sense.
[0] = '\xa4'
[1] = '\xb4'
[2] = '\xca'
[3] = '\x17'
[4] = '\xcc'
[5] = '\xa6'
[6] = '\xc7'
[7] = 'n'
Going further consider this next step:
hmac_pwh = HMAC-SHA512(pwh, base64decode(login_session))//hmac_pwh is hex encoded
I believe a correct mapping looks like this with a helper category:
NSData *decodedData = [NSData dataFromBase64String:@"lgHZIDhlY2I0..."];
uint8_t *decodedCString = (uint8_t *)decodedData.bytes;
unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA512, pwh, 224 - 192, decodedCString, 108, cHMAC);
the cHMAC buffer doesn't look right either: "\xca\x93 \xc2\xd7"\xfe\xd7\xc9\xa8..."
When converting the cHMAC string back into a NSString, my suspicions are confirmed as
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *HMACString = [[NSString alloc] initWithData:HMAC encoding:NSASCIIStringEncoding];
Results in HMACString looking like this "Ê Â×"þ×ɨ©..."
I believe this is a encoding/decoding issue since NSString is UTF-8 encoded but I can officially say that it's above my head. Does cHMAC need to be decoded from binary into hexadecimal before being encoded as a string?
Any help, however small, would be appreciated.
Answer:
The answer is that I wasn't encoding/decoding to and from hex to binary as pointed out by Max.
To get from cHMAC to a NSString representation of HMAC you can do something like this. My interpretation:
NSString* hmac(unsigned int size, unsigned char cHMAC[size])
{
NSMutableString *result = [NSMutableString string];
for (int i = 0; i < size; i++)
{
[result appendFormat:@"%02hhx", cHMAC[i]];
}
return result;
}
And invoked as such:
NSString *result = hmac(CC_SHA512_DIGEST_LENGTH, cHMAC);