/* Serval Distributed Numbering Architecture (DNA) Copyright (C) 2010 Paul Gardner-Stephen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include "crypto_box_curve25519xsalsa20poly1305.h" #include "crypto_sign_edwards25519sha512batch.h" // Lto/yp/cr/NaCl;.moose ()I JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_moose (JNIEnv *env, jobject obj) { return 1; } JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeRandomBytes (JNIEnv *env, jobject obj, jbyteArray bytes) { int l=(*env)->GetArrayLength(env, bytes); if (l<1) return -1; jbyte *b = (*env)->GetPrimitiveArrayCritical(env, bytes, NULL); urandombytes(b,l); if (b) (*env)->ReleasePrimitiveArrayCritical(env, bytes, b, 0); return 0; } /* ------------------------------------------------------------------------ crypto_box functions : Diffie-Hellman negotiated symmetric cryptography CryptoBoxKeypair - generate key pair. CryptoBox - Create authenticated an encrypted message. CryptoBoxOpen - Decode and verify an en encrypted message. ------------------------------------------------------------------------ */ // Lto/yp/cr/NaCl$CryptoBoxKeypair;.method ([B[B)I JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeCryptoBoxKeypair (JNIEnv *env, jobject obj, jbyteArray jsk, jbyteArray jpk) { unsigned char pk[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES]; unsigned char sk[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES]; if (crypto_box_curve25519xsalsa20poly1305_keypair(pk,sk)) return 1; /* Set java side versions of pk and sk */ (*env)->SetByteArrayRegion(env, jpk, 0, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES, pk); (*env)->SetByteArrayRegion(env, jsk, 0, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES, sk); return 0; } JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeCryptoBox (JNIEnv *env, jobject obj, jbyteArray jpk, jbyteArray jsk,jbyteArray jn,jbyteArray jm,jint jmlen,jbyteArray jc) { int i; if ((*env)->GetArrayLength(env, jpk)!=crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return -2; if ((*env)->GetArrayLength(env, jsk)!=crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) return -3; if ((*env)->GetArrayLength(env, jn)!=crypto_box_curve25519xsalsa20poly1305_NONCEBYTES) return -4; if ((*env)->GetArrayLength(env, jm)!=jmlen) return -5; if ((*env)->GetArrayLength(env, jc)!=jmlen) return -6; /* Get inputs */ jbyte *pk = (*env)->GetPrimitiveArrayCritical(env, jpk, NULL); jbyte *sk = (*env)->GetPrimitiveArrayCritical(env, jsk, NULL); jbyte *n = (*env)->GetPrimitiveArrayCritical(env, jn, NULL); jbyte *m = (*env)->GetPrimitiveArrayCritical(env, jm, NULL); jbyte *c = (*env)->GetPrimitiveArrayCritical(env, jc, NULL); int r=-1; if (pk&&sk&&n&&m&&c&&(jmlen>=0&&jmlen<=1048576)) { /* Make sure that space for authenticator is zeroed */ for(i=0;iReleasePrimitiveArrayCritical(env, jpk, pk, 0); if (sk) (*env)->ReleasePrimitiveArrayCritical(env, jsk, sk, 0); if (n) (*env)->ReleasePrimitiveArrayCritical(env, jn, n, 0); if (m) (*env)->ReleasePrimitiveArrayCritical(env, jm, m, 0); if (c) (*env)->ReleasePrimitiveArrayCritical(env, jc, c, 0); return r; } JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeCryptoBoxOpen (JNIEnv *env, jobject obj, jbyteArray jpk, jbyteArray jsk,jbyteArray jn,jbyteArray jm,jint jclen,jbyteArray jc) { int i; if ((*env)->GetArrayLength(env, jpk)!=crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return -2; if ((*env)->GetArrayLength(env, jsk)!=crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) return -3; if ((*env)->GetArrayLength(env, jn)!=crypto_box_curve25519xsalsa20poly1305_NONCEBYTES) return -4; if ((*env)->GetArrayLength(env, jm)!=jclen) return -5; if ((*env)->GetArrayLength(env, jc)!=jclen) return -6; /* Get inputs */ jbyte *pk = (*env)->GetPrimitiveArrayCritical(env, jpk, NULL); jbyte *sk = (*env)->GetPrimitiveArrayCritical(env, jsk, NULL); jbyte *n = (*env)->GetPrimitiveArrayCritical(env, jn, NULL); jbyte *m = (*env)->GetPrimitiveArrayCritical(env, jm, NULL); jbyte *c = (*env)->GetPrimitiveArrayCritical(env, jc, NULL); int r=-1; if (pk&&sk&&n&&m&&c&&(jclen>=0&&jclen<=1048576)) { /* Make sure that space for authenticator is free */ for(i=0;iReleasePrimitiveArrayCritical(env, jpk, pk, 0); if (sk) (*env)->ReleasePrimitiveArrayCritical(env, jsk, sk, 0); if (n) (*env)->ReleasePrimitiveArrayCritical(env, jn, n, 0); if (m) (*env)->ReleasePrimitiveArrayCritical(env, jm, m, 0); if (c) (*env)->ReleasePrimitiveArrayCritical(env, jc, c, 0); return r; } /* ------------------------------------------------------------------------ crypto_sign functions : Public key cryptography functions ------------------------------------------------------------------------ */ JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeCryptoSignKeypair (JNIEnv *env, jobject obj, jbyteArray jsk, jbyteArray jpk) { unsigned char pk[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES]; unsigned char sk[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]; if (crypto_sign_edwards25519sha512batch_keypair(pk,sk)) return 1; /* Set java side versions of pk and sk */ (*env)->SetByteArrayRegion(env, jpk, 0, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES, pk); (*env)->SetByteArrayRegion(env, jsk, 0, crypto_sign_edwards25519sha512batch_SECRETKEYBYTES, sk); return 0; } JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeCryptoSign (JNIEnv *env, jobject obj, jbyteArray jsk,jbyteArray jm,jbyteArray jsm) { long long mlen,smlen,smlen_in; smlen=(*env)->GetArrayLength(env, jsm); smlen_in=smlen; mlen=(*env)->GetArrayLength(env, jm); if ((smlen-mlen)!=crypto_sign_edwards25519sha512batch_BYTES) return -4; if ((*env)->GetArrayLength(env, jsk)!=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES) return -3; /* Get inputs */ jbyte *sk = (*env)->GetPrimitiveArrayCritical(env, jsk, NULL); jbyte *m = (*env)->GetPrimitiveArrayCritical(env, jm, NULL); jbyte *sm = (*env)->GetPrimitiveArrayCritical(env, jsm, NULL); int r=-1; if (sk&&m&&sm) { r=crypto_sign_edwards25519sha512batch_ref(sm,&smlen,m,mlen,sk); if (smlen!=smlen_in) return -5; } /* do these really keep any changes made? */ if (sk) (*env)->ReleasePrimitiveArrayCritical(env, jsk, sk, 0); if (m) (*env)->ReleasePrimitiveArrayCritical(env, jm, m, 0); if (sm) (*env)->ReleasePrimitiveArrayCritical(env, jsm, sm, 0); return r; } JNIEXPORT jint JNICALL Java_to_yp_cr_NaCl_nativeCryptoSignOpen (JNIEnv *env, jobject obj, jbyteArray jpk,jbyteArray jsm,jbyteArray jm) { long long mlen,smlen,mlen_in; smlen=(*env)->GetArrayLength(env, jsm); mlen=(*env)->GetArrayLength(env, jm); mlen_in=mlen; if (smlen>mlen) return -4; if ((*env)->GetArrayLength(env, jpk)!=crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES) return -3; /* Get inputs */ jbyte *pk = (*env)->GetPrimitiveArrayCritical(env, jpk, NULL); jbyte *m = (*env)->GetPrimitiveArrayCritical(env, jm, NULL); jbyte *sm = (*env)->GetPrimitiveArrayCritical(env, jsm, NULL); int r=-1; if (pk&&m&&sm) { r=crypto_sign_edwards25519sha512batch_open(m,&mlen,sm,smlen,pk); if (mlen!=mlen_in) return -5; } /* do these really keep any changes made? */ if (pk) (*env)->ReleasePrimitiveArrayCritical(env, jpk, pk, 0); if (m) (*env)->ReleasePrimitiveArrayCritical(env, jm, m, 0); if (sm) (*env)->ReleasePrimitiveArrayCritical(env, jsm, sm, 0); return r; }