From 046821e422a9cd673d2caf39be914b817de0167e Mon Sep 17 00:00:00 2001 From: Silke Date: Mon, 20 Mar 2017 17:37:24 +0100 Subject: [PATCH] Add and fix CryptoAEADAES256GCM functions - Fix CryptoAEADAES256GCMNSecBytes() - Remove nsec from CryptoAEADAES256GCMEncrypt() and Decrypt() - Add support.CheckSizeMin for things with a minimum size - Add support.BytePointer to get a pointer for things than can have 0 length - Add CryptoAEADAES256GCMIsAvailable(), CryptoAEADAES256GCMEncryptDetached(), CryptoAEADAES256GCMDecryptDetached() and CryptoAEADAES256GCMKeyGen() Closes #9 --- cryptoaead/crypto_aead_aes256gcm.go | 93 ++++++++++++++++++++++------- support/support.go | 14 +++++ 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/cryptoaead/crypto_aead_aes256gcm.go b/cryptoaead/crypto_aead_aes256gcm.go index c7b1ace..fa81774 100644 --- a/cryptoaead/crypto_aead_aes256gcm.go +++ b/cryptoaead/crypto_aead_aes256gcm.go @@ -6,12 +6,17 @@ package cryptoaead import "C" import "github.com/GoKillers/libsodium-go/support" +func CryptoAEADAES256GCMIsAvailable() bool { + C.sodium_init() + return int(C.crypto_aead_aes256gcm_is_available()) != 0 +} + func CryptoAEADAES256GCMKeyBytes() int { return int(C.crypto_aead_aes256gcm_keybytes()) } func CryptoAEADAES256GCMNSecBytes() int { - return int(C.crypto_aead_aes256gcm_keybytes()) + return int(C.crypto_aead_aes256gcm_nsecbytes()) } func CryptoAEADAES256GCMNPubBytes() int { @@ -26,47 +31,95 @@ func CryptoAEADAES256GCMStateBytes() int { return int(C.crypto_aead_aes256gcm_statebytes()) } -func CryptoAESAES256GCMIsAvailable() int { - return int(C.crypto_aead_aes256gcm_is_available()) -} - -func CryptoAEADAES256GCMEncrypt(m []byte, ad []byte, nsec []byte, npub []byte, k []byte) ([]byte, int) { +func CryptoAEADAES256GCMEncrypt(m []byte, ad []byte, npub []byte, k []byte) ([]byte, int) { support.CheckSize(k, CryptoAEADAES256GCMKeyBytes(), "secret key") support.CheckSize(npub, CryptoAEADAES256GCMNPubBytes(), "public nonce") + c := make([]byte, len(m)+CryptoAEADAES256GCMABytes()) - cLen := len(c) - cLenLongLong := (C.ulonglong(cLen)) + cLen := C.ulonglong(len(c)) + exit := int(C.crypto_aead_aes256gcm_encrypt( - (*C.uchar)(&c[0]), - &cLenLongLong, - (*C.uchar)(&m[0]), + (*C.uchar)(support.BytePointer(c)), + (*C.ulonglong)(&cLen), + (*C.uchar)(support.BytePointer(m)), (C.ulonglong)(len(m)), - (*C.uchar)(&ad[0]), + (*C.uchar)(support.BytePointer(ad)), (C.ulonglong)(len(ad)), - (*C.uchar)(&nsec[0]), + (*C.uchar)(nil), (*C.uchar)(&npub[0]), (*C.uchar)(&k[0]))) return c, exit } -func CryptoAEADAES256GCMDecrypt(nsec []byte, c []byte, ad []byte, npub []byte, k []byte) ([]byte, int) { +func CryptoAEADAES256GCMDecrypt(c []byte, ad []byte, npub []byte, k []byte) ([]byte, int) { support.CheckSize(k, CryptoAEADAES256GCMKeyBytes(), "secret key") support.CheckSize(npub, CryptoAEADAES256GCMNPubBytes(), "public nonce") + support.CheckSizeMin(c, CryptoAEADAES256GCMABytes(), "ciphertext") + m := make([]byte, len(c)-CryptoAEADAES256GCMABytes()) - mLen := len(m) - mLenLongLong := (C.ulonglong)(mLen) + mLen := (C.ulonglong)(len(m)) exit := int(C.crypto_aead_aes256gcm_decrypt( - (*C.uchar)(&m[0]), - &mLenLongLong, - (*C.uchar)(&nsec[0]), + (*C.uchar)(support.BytePointer(m)), + (*C.ulonglong)(&mLen), + (*C.uchar)(nil), (*C.uchar)(&c[0]), (C.ulonglong)(len(c)), - (*C.uchar)(&ad[0]), + (*C.uchar)(support.BytePointer(ad)), + (C.ulonglong)(len(ad)), + (*C.uchar)(&npub[0]), + (*C.uchar)(&k[0]))) + + return m, exit +} + +func CryptoAEADAES256GCMEncryptDetached(m []byte, ad []byte, npub []byte, k []byte) ([]byte, []byte, int) { + support.CheckSize(k, CryptoAEADAES256GCMKeyBytes(), "secret key") + support.CheckSize(npub, CryptoAEADAES256GCMNPubBytes(), "public nonce") + + c := make([]byte, len(m)) + mac := make([]byte , CryptoAEADAES256GCMABytes()) + macLen := C.ulonglong(len(c)) + + exit := int(C.crypto_aead_aes256gcm_encrypt_detached( + (*C.uchar)(support.BytePointer(c)), + (*C.uchar)(&mac[0]), + (*C.ulonglong)(&macLen), + (*C.uchar)(support.BytePointer(m)), + (C.ulonglong)(len(m)), + (*C.uchar)(support.BytePointer(ad)), + (C.ulonglong)(len(ad)), + (*C.uchar)(nil), + (*C.uchar)(&npub[0]), + (*C.uchar)(&k[0]))) + + return c, mac, exit +} + +func CryptoAEADAES256GCMDecryptDetached(c, mac, ad, npub, k []byte) ([]byte, int) { + support.CheckSize(k, CryptoAEADAES256GCMKeyBytes(), "secret key") + support.CheckSize(npub, CryptoAEADAES256GCMNPubBytes(), "public nonce") + support.CheckSize(mac, CryptoAEADAES256GCMABytes(), "mac") + + m := make([]byte, len(c)) + + exit := int(C.crypto_aead_aes256gcm_decrypt_detached( + (*C.uchar)(support.BytePointer(m)), + (*C.uchar)(nil), + (*C.uchar)(support.BytePointer(c)), + (C.ulonglong)(len(c)), + (*C.uchar)(&mac[0]), + (*C.uchar)(support.BytePointer(ad)), (C.ulonglong)(len(ad)), (*C.uchar)(&npub[0]), (*C.uchar)(&k[0]))) return m, exit } + +func CryptoAEADAES256GCMKeyGen() []byte { + k := make([]byte, CryptoAEADAES256GCMKeyBytes()) + C.crypto_aead_aes256gcm_keygen((*C.uchar)(&k[0])) + return k +} diff --git a/support/support.go b/support/support.go index 12dc6d7..cbac049 100644 --- a/support/support.go +++ b/support/support.go @@ -13,8 +13,22 @@ func CheckSize(buf []byte, expected int, descrip string) { } } +func CheckSizeMin(buf []byte, min int, descrip string) { + if len(buf) < min { + panic(fmt.Sprintf("Incorrect %s buffer size, expected (>%d), got (%d).", descrip, min, len(buf))) + } +} + func CheckSizeInRange(size int, min int, max int, descrip string) { if size < min || size > max { panic(fmt.Sprintf("Incorrect %s buffer size, expected (%d - %d), got (%d).", descrip, min, max, size)) } } + +func BytePointer(b []byte) *uint8 { + if len(b) > 0 { + return &b[0] + } else { + return nil + } +}