Subject: | [PATCH] get rid of hand coded padding , add crypto_secretbox(), add crypto_pwhash_scrypt() |
Hello Michael,
the following patch adds and changes a couple of things:
1) I replaced the crypto_box[_open] functions with their _easy counterparts and removed the padding code, since the _easy functions in libsodium already implement this.
2) I added crypto_secretbox() and crypto_secretbox_open() for symmetric encryption.
3) I added crypto_pwhash_salt() to generate a salt and crypto_pwhash_scrypt() to derive a secure key from a passphrase.
I also added a couple of constants required for those changes. POD updated accordingly.
Usage sample:
use Crypt::Sodium;
use MIME::Base64;
# sym encrypt
my $n = crypto_box_nonce();
my $k = randombytes_buf(32);
my $m = 'hello';
# sym decrypt
my $c = crypto_secretbox($m, $n, $k);
my $a = crypto_secretbox_open($c, $n, $k);
print "ok\n" if ($a eq $m);
# gen salt for keygen
my $salt = crypto_pwhash_salt();
print encode_base64($salt);
# derive a key
my $hash = crypto_pwhash_scrypt($m, $salt, 128);
# repeat
my $hash2 = crypto_pwhash_scrypt($m, $salt, 128);
print "ok\n" if($hash eq $hash2);
best regards,
Tom
Subject: | crypt-sodium-easy-scrypt-20110319.patch |
diff -c Crypt-Sodium-0.06/Sodium.xs Crypt-Sodium-0.07/Sodium.xs
*** Crypt-Sodium-0.06/Sodium.xs 2015-01-23 17:27:29.000000000 +0100
--- Crypt-Sodium-0.07/Sodium.xs 2015-03-19 21:48:04.000000000 +0100
***************
*** 53,58 ****
--- 53,66 ----
RETVAL
SV *
+ crypto_box_SEEDBYTES()
+ CODE:
+ RETVAL = newSVuv((unsigned int) crypto_box_SEEDBYTES);
+
+ OUTPUT:
+ RETVAL
+
+ SV *
crypto_sign_PUBLICKEYBYTES()
CODE:
RETVAL = newSVuv((unsigned int) crypto_sign_PUBLICKEYBYTES);
***************
*** 61,66 ****
--- 69,91 ----
RETVAL
SV *
+ crypto_secretbox_MACBYTES()
+ CODE:
+ RETVAL = newSVuv((unsigned int) crypto_secretbox_MACBYTES);
+
+ OUTPUT:
+ RETVAL
+
+ SV *
+ crypto_box_MACBYTES()
+ CODE:
+ RETVAL = newSVuv((unsigned int) crypto_box_MACBYTES);
+
+ OUTPUT:
+ RETVAL
+
+
+ SV *
crypto_sign_SECRETKEYBYTES()
CODE:
RETVAL = newSVuv((unsigned int) crypto_sign_SECRETKEYBYTES);
***************
*** 69,74 ****
--- 94,123 ----
RETVAL
SV *
+ crypto_pwhash_SALTBYTES()
+ CODE:
+ RETVAL = newSVuv((unsigned int) crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
+
+ OUTPUT:
+ RETVAL
+
+ SV *
+ crypto_pwhash_OPSLIMIT()
+ CODE:
+ RETVAL = newSVuv((unsigned int) crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE);
+
+ OUTPUT:
+ RETVAL
+
+ SV *
+ crypto_pwhash_MEMLIMIT()
+ CODE:
+ RETVAL = newSVuv((unsigned int) crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);
+
+ OUTPUT:
+ RETVAL
+
+ SV *
randombytes_random()
CODE:
uint32_t r_bytes = randombytes_random();
***************
*** 126,182 ****
unsigned char * sk
CODE:
! int padding_required = 0;
! unsigned long original_clen = clen;
!
! int bytes_of_zeroes = crypto_box_BOXZEROBYTES;
! unsigned char * padding[bytes_of_zeroes];
! memset(padding, 0, bytes_of_zeroes);
!
! // check to see if we already have bytes_of_zeroes up front
! if (memcmp(c, padding, bytes_of_zeroes) != 0) {
! // some padding is required, let's determine how much.
! padding_required = 1;
!
! int bytes_in_a_row = bytes_of_zeroes;
! for (bytes_in_a_row = bytes_of_zeroes; bytes_in_a_row > 0; --bytes_in_a_row) {
! if (memcmp(c, padding, bytes_in_a_row) == 0) {
! break;
! }
! }
!
! // this is how many zeroes we have to add.
! bytes_of_zeroes = (bytes_of_zeroes - bytes_in_a_row);
! clen += bytes_of_zeroes;
! }
!
! unsigned char * m = malloc(clen);
! unsigned char * padded_c = malloc(clen);
!
! // do padding if we've determined we have to.
! if (padding_required == 1) {
! // set crypto_box_BOXZEROBYTES zeroes at the beginning
! memset(padded_c, 0, bytes_of_zeroes);
!
! // copy in our payload (including zeroes it may have come with)
! memcpy(padded_c + bytes_of_zeroes, c, original_clen);
! } else {
! // just copy the message, it's already good to go.
! memcpy(padded_c, c, clen);
! }
! int status = crypto_box_open((unsigned char *)m, (const unsigned char*)padded_c,
(unsigned long long) clen, (const unsigned char*)n, (const unsigned char*)pk, (const unsigned char*)sk);
//printf("open_crypto_box Status is: %d\n", status);
- // get rid of the zero padding...
- unsigned char cleartext[(clen - crypto_box_ZEROBYTES) + 1];
- memcpy( cleartext, &m[crypto_box_ZEROBYTES], clen - crypto_box_ZEROBYTES );
- cleartext[(clen - crypto_box_ZEROBYTES)] = 0;
-
if (status == 0) {
! RETVAL = newSVpv( cleartext, clen - crypto_box_ZEROBYTES );
} else {
RETVAL = &PL_sv_undef;
}
--- 175,189 ----
unsigned char * sk
CODE:
! unsigned char * m = malloc(clen - crypto_box_MACBYTES);
! int status = crypto_box_open_easy((unsigned char *)m, (const unsigned char*)c,
(unsigned long long) clen, (const unsigned char*)n, (const unsigned char*)pk, (const unsigned char*)sk);
//printf("open_crypto_box Status is: %d\n", status);
if (status == 0) {
! RETVAL = newSVpv( m, clen - crypto_box_MACBYTES );
} else {
RETVAL = &PL_sv_undef;
}
***************
*** 193,262 ****
unsigned char * sk
CODE:
! int padding_required = 0;
! unsigned long original_mlen = mlen;
! int bytes_of_zeroes = crypto_box_ZEROBYTES;
! unsigned char * padding[bytes_of_zeroes];
! memset(padding, 0, bytes_of_zeroes);
!
! // check to see if we already have bytes_of_zeroes up front
! if (memcmp(m, padding, crypto_box_ZEROBYTES) != 0) {
! // some padding is required, let's determine how much.
! padding_required = 1;
!
! int bytes_in_a_row = bytes_of_zeroes;
! for (bytes_in_a_row = bytes_of_zeroes; bytes_in_a_row > 0; --bytes_in_a_row) {
! if (memcmp(m, padding, bytes_in_a_row) == 0) {
! break;
! }
! }
!
! // this is how many zeroes we have to add.
! bytes_of_zeroes = (bytes_of_zeroes - bytes_in_a_row);
! mlen += bytes_of_zeroes;
! }
! unsigned char * c = malloc(mlen);
! unsigned char * padded_m = malloc(mlen);
! // do padding if we've determined we have to.
! if (padding_required == 1) {
! // set crypto_box_ZEROBYTES zeroes at the beginning
! memset(padded_m, 0, bytes_of_zeroes);
! // copy in our payload (including zeroes it may have come with)
! memcpy(padded_m + bytes_of_zeroes, m, original_mlen);
} else {
! // just copy the message, it's already good to go.
! memcpy(padded_m, m, mlen);
}
! int status = crypto_box((unsigned char *)c, (const unsigned char*)padded_m,
! (unsigned long long) mlen, (const unsigned char*)n, (const unsigned char*)pk, (const unsigned char*)sk);
- //printf("crypto_box Status is: %d\n", status);
! // the message is at least this big.
! unsigned char ciphertext[mlen];
! int clen = 0;
! int i;
! for (i = 0; i < mlen; i++) {
! if ( !(c[i] == 0) || (clen > 0) ) {
! ciphertext[clen] = c[i];
! clen++;
! }
! }
! // make sure to terminate
! ciphertext[clen + 1] = 0;
! RETVAL = newSVpv( ciphertext, clen );
OUTPUT:
RETVAL
SV *
real_crypto_hash(in, inlen)
unsigned char * in
--- 200,270 ----
unsigned char * sk
CODE:
! unsigned char * c = malloc(mlen + crypto_box_MACBYTES);
! int status = crypto_box_easy((unsigned char *)c, (const unsigned char*)m,
! (unsigned long long) mlen, (const unsigned char*)n, (const unsigned char*)pk, (const unsigned char*)sk);
!
! //printf("crypto_box Status is: %d\n", status);
! if (status == 0) {
! RETVAL = newSVpv( c, mlen + crypto_box_MACBYTES);
! } else {
! RETVAL = &PL_sv_undef;
! }
!
! OUTPUT:
! RETVAL
!
!
! SV *
! real_crypto_secretbox_open(c, clen, n, sk)
! unsigned char * c
! unsigned long clen
! unsigned char * n
! unsigned char * sk
!
! CODE:
! unsigned char * m = malloc(clen - crypto_secretbox_MACBYTES);
! int status = crypto_secretbox_open_easy((unsigned char *)m, (const unsigned char*)c,
! (unsigned long long) clen, (const unsigned char*)n, (const unsigned char*)sk);
! if (status == 0) {
! RETVAL = newSVpv( m, clen - crypto_secretbox_MACBYTES );
} else {
! RETVAL = &PL_sv_undef;
}
! OUTPUT:
! RETVAL
! SV *
! real_crypto_secretbox(m, mlen, n, sk)
! unsigned char * m
! unsigned long mlen
! unsigned char * n
! unsigned char * sk
! CODE:
! unsigned char * c = malloc(mlen + crypto_secretbox_MACBYTES);
! int status = crypto_secretbox_easy((unsigned char *)c, (const unsigned char*)m,
! (unsigned long long) mlen, (const unsigned char*)n, (const unsigned char*)sk);
! if (status == 0) {
! RETVAL = newSVpv( c, mlen + crypto_secretbox_MACBYTES );
! } else {
! RETVAL = &PL_sv_undef;
! }
OUTPUT:
RETVAL
+
+
+
SV *
real_crypto_hash(in, inlen)
unsigned char * in
***************
*** 353,355 ****
--- 361,386 ----
OUTPUT:
RETVAL
+
+ SV *
+ real_crypto_pwhash_scrypt(klen, p, salt, opslimit, memlimit)
+ unsigned long klen
+ unsigned char *p
+ unsigned char *salt
+ unsigned long opslimit
+ unsigned long memlimit
+
+ CODE:
+ unsigned char *k = malloc(klen);
+
+ int status = crypto_pwhash_scryptsalsa208sha256((unsigned char *)k, klen,
+ (unsigned char *)p, strlen(p), (const unsigned char *)salt, opslimit, memlimit);
+
+ if (status == 0) {
+ RETVAL = newSVpv((unsigned char *)k, klen);
+ } else {
+ RETVAL = &PL_sv_undef;
+ }
+
+ OUTPUT:
+ RETVAL
Common subdirectories: Crypt-Sodium-0.06/lib and Crypt-Sodium-0.07/lib
Common subdirectories: Crypt-Sodium-0.06/t and Crypt-Sodium-0.07/t