Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symmetric keygen: high-level wrappers #561

Merged
merged 13 commits into from
Dec 11, 2019
Merged
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,45 @@ _Code:_

- New function `themis_gen_sym_key()` can be used to securely generate symmetric keys for Secure Cell ([#560](https://github.com/cossacklabs/themis/pull/560)).

- **C++**

- New function `themispp::gen_sym_key()` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **Go**

- New function `keys.NewSymmetricKey()` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **iOS and macOS**

- New function `TSGenerateSymmetricKey()` (available in Objective-C and Swift) can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **Java**

- JDK location is now detected automatically in most cases, you should not need to set JAVA_HOME or JDK_INCLUDE_PATH manually ([#551](https://github.com/cossacklabs/themis/pull/551)).
- JNI libraries are now available as `libthemis-jni` packages for supported Linux systems ([#552](https://github.com/cossacklabs/themis/pull/552), [#553](https://github.com/cossacklabs/themis/pull/553)).
- Fixed a NullPointerException bug in `SecureSocket` initialisation ([#557](https://github.com/cossacklabs/themis/pull/557)).
- Some Themis exceptions have been converted from checked `Exception` to _unchecked_ `RuntimeException`, relaxing requirements for `throws` specifiers ([#563](https://github.com/cossacklabs/themis/pull/563)).

- **PHP**

- New function `phpthemis_gen_sym_key()` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **Python**

- Fixed compatibility issues on 32-bit platforms ([#555](https://github.com/cossacklabs/themis/pull/555)).
- New function `skeygen.GenerateSymmetricKey()` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **Ruby**

- New function `Themis::gen_sym_key()` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **Rust**

- New object `themis::keys::SymmetricKey` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

- **WebAssembly**

- New class `SymmetricKey` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).

## [0.12.0](https://github.com/cossacklabs/themis/releases/tag/0.12.0), September 27th 2019

Expand Down
46 changes: 46 additions & 0 deletions gothemis/keys/symmetric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package keys

/*
#cgo LDFLAGS: -lthemis

#include <stdbool.h>
#include <themis/themis.h>

static bool get_sym_key_size(size_t *key_len)
{
return themis_gen_sym_key(NULL, key_len) == THEMIS_BUFFER_TOO_SMALL;
}

static bool gen_sym_key(void *key, size_t key_len)
{
return themis_gen_sym_key(key, &key_len) == THEMIS_SUCCESS;
}

*/
import "C"

import (
"unsafe"

"github.com/cossacklabs/themis/gothemis/errors"
)

// SymmetricKey stores a master key for Secure Cell.
type SymmetricKey struct {
Value []byte
}

// NewSymmetricKey generates a new random symmetric key.
func NewSymmetricKey() (*SymmetricKey, error) {
var len C.size_t
if !bool(C.get_sym_key_size(&len)) {
return nil, errors.New("Failed to get symmetric key size")
}

key := make([]byte, int(len), int(len))
if !bool(C.gen_sym_key(unsafe.Pointer(&key[0]), len)) {
return nil, errors.New("Failed to generate symmetric key")
}

return &SymmetricKey{Value: key}, nil
}
17 changes: 17 additions & 0 deletions gothemis/keys/symmetric_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package keys

import (
"testing"
)

const defaultLength = 32

func TestNewSymmetricKey(t *testing.T) {
key, err := NewSymmetricKey()
if err != nil {
t.Error(err)
}
if len(key.Value) != defaultLength {
t.Error("invalid key.Value")
}
}
9 changes: 9 additions & 0 deletions src/wrappers/themis/Obj-C/objcthemis/skeygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ typedef NS_ENUM(NSInteger, TSKeyGenAsymmetricAlgorithm) {

@end

/**
* Generates new symmetric master key.
*
* Securely generate a new master key suitable for Secure Cell.
*
* @returns a newly allocated key of default size.
*/
NSData* __nullable TSGenerateSymmetricKey();

NS_ASSUME_NONNULL_END

/** @} */
Expand Down
21 changes: 21 additions & 0 deletions src/wrappers/themis/Obj-C/objcthemis/skeygen.m
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,24 @@ - (TSErrorType)generateKeys {
}

@end

NSData* __nullable TSGenerateSymmetricKey()
{
TSErrorType result;
NSMutableData *key;
size_t keyLength = 0;

result = (TSErrorType) themis_gen_sym_key(NULL, &keyLength);
if (result != TSErrorTypeBufferTooSmall) {
return nil;
}

key = [NSMutableData dataWithLength:keyLength];

result = (TSErrorType) themis_gen_sym_key(key.mutableBytes, &keyLength);
if (result != TSErrorTypeSuccess) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (result != TSErrorTypeSuccess) {
if (result != TSErrorTypeSuccess) {
[key resetBytesInRange:NSMakeRange(0, [key length])];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[key resetBytesInRange:NSMakeRange(0, [key length])];

I'd think this will be excessive when these suggestion is implemented in Themis Core. It will ensure that if themis_gen_sym_key() fails then output buffer does not contain anything useful or sensitive. That way we will not need to add additional wiping to every single wrapper individually.

Copy link
Contributor

@vixentael vixentael Dec 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree.

another reason I suggested it for iOS only – I don't know how to zeroing bytes in every other language :D

return nil;
}

return key;
}
22 changes: 21 additions & 1 deletion src/wrappers/themis/php/php_themis.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ static zend_function_entry php_themis_functions[] = {
PHP_FE(phpthemis_secure_message_unwrap, NULL)
PHP_FE(phpthemis_gen_rsa_key_pair, NULL)
PHP_FE(phpthemis_gen_ec_key_pair, NULL)
PHP_FE(phpthemis_gen_sym_key, NULL)
PHP_FE(phpthemis_scell_seal_encrypt, NULL)
PHP_FE(phpthemis_scell_seal_decrypt, NULL)
PHP_FE(phpthemis_scell_token_protect_encrypt,NULL)
Expand Down Expand Up @@ -397,6 +398,25 @@ PHP_FUNCTION(phpthemis_gen_ec_key_pair){
add_assoc_stringl(return_value, "public_key", public_key, public_key_length, 0);
}

PHP_FUNCTION(phpthemis_gen_sym_key){
size_t key_length;
if(themis_gen_sym_key(NULL, &key_length)!=THEMIS_BUFFER_TOO_SMALL){
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Error: themis_gen_sym_key: invalid parameters.", 0 TSRMLS_CC);
RETURN_NULL();
}
uint8_t* key=emalloc(key_length);
if(key==NULL){
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Error: themis_gen_sym_key: not enough memory.", 0 TSRMLS_CC);
RETURN_NULL();
}
if(themis_gen_sym_key(key, &key_length)!=THEMIS_SUCCESS){
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Error: themis_gen_sym_key: generation failed.", 0 TSRMLS_CC);
RETURN_NULL();
}
ZVAL_STRINGL(return_value, key, (int)key_length, 0);
return;
}

PHP_FUNCTION(phpthemis_scell_seal_encrypt){
char* key;
int key_length;
Expand Down Expand Up @@ -579,4 +599,4 @@ PHP_FUNCTION(phpthemis_scell_context_imprint_decrypt){
}
ZVAL_STRINGL(return_value, decrypted_message, (int)decrypted_message_length, 0);
return;
}
}
1 change: 1 addition & 0 deletions src/wrappers/themis/php/php_themis.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ PHP_FUNCTION(phpthemis_secure_message_unwrap);
PHP_FUNCTION(phpthemis_gen_rsa_key_pair);
PHP_FUNCTION(phpthemis_gen_ec_key_pair);

PHP_FUNCTION(phpthemis_gen_sym_key);
PHP_FUNCTION(phpthemis_scell_seal_encrypt);
PHP_FUNCTION(phpthemis_scell_seal_decrypt);
PHP_FUNCTION(phpthemis_scell_token_protect_encrypt);
Expand Down
21 changes: 20 additions & 1 deletion src/wrappers/themis/php7/php_key_generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,23 @@ ZEND_FUNCTION(phpthemis_gen_ec_key_pair){
array_init(return_value);
add_assoc_stringl(return_value, "private_key", private_key, private_key_length);
add_assoc_stringl(return_value, "public_key", public_key, public_key_length);
}
}

ZEND_FUNCTION(phpthemis_gen_sym_key){
size_t key_length;
if(themis_gen_sym_key(NULL, &key_length)!=THEMIS_BUFFER_TOO_SMALL){
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Error: themis_gen_sym_key: invalid parameters.", 0 TSRMLS_CC);
RETURN_NULL();
}
uint8_t* key=emalloc(key_length);
if(key==NULL){
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Error: themis_gen_sym_key: not enough memory.", 0 TSRMLS_CC);
RETURN_NULL();
}
if(themis_gen_sym_key(key, &key_length)!=THEMIS_SUCCESS){
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Error: themis_gen_sym_key: generation failed.", 0 TSRMLS_CC);
RETURN_NULL();
}
ZVAL_STRINGL(return_value, key, (int)key_length);
return;
}
2 changes: 2 additions & 0 deletions src/wrappers/themis/php7/php_key_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@
ZEND_FUNCTION(phpthemis_gen_rsa_key_pair);
ZEND_FUNCTION(phpthemis_gen_ec_key_pair);

ZEND_FUNCTION(phpthemis_gen_sym_key);

#endif //THEMIS_KEY_GENERATOR_H
1 change: 1 addition & 0 deletions src/wrappers/themis/php7/php_themis.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static zend_function_entry php_themis_functions[] = {
ZEND_FE(phpthemis_secure_message_unwrap, NULL)
ZEND_FE(phpthemis_gen_rsa_key_pair, NULL)
ZEND_FE(phpthemis_gen_ec_key_pair, NULL)
ZEND_FE(phpthemis_gen_sym_key, NULL)
ZEND_FE(phpthemis_scell_seal_encrypt, NULL)
ZEND_FE(phpthemis_scell_seal_decrypt, NULL)
ZEND_FE(phpthemis_scell_token_protect_encrypt, NULL)
Expand Down
15 changes: 15 additions & 0 deletions src/wrappers/themis/python/pythemis/skeygen.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,18 @@ def __init__(self, *args, **kwargs):
warnings.warn("themis_gen_key_pair is deprecated in favor of "
"GenerateKeyPair.")
super(themis_gen_key_pair, self).__init__(*args, **kwargs)


def GenerateSymmetricKey():
"""Returns a byte string with newly generated key."""
key_length = c_int(0)
res = themis.themis_gen_sym_key(None, byref(key_length))
if res != THEMIS_CODES.BUFFER_TOO_SMALL:
raise ThemisError(res, "Themis failed to get symmetric key size")

key = create_string_buffer(key_length.value)
res = themis.themis_gen_sym_key(key, byref(key_length))
if res != THEMIS_CODES.SUCCESS:
raise ThemisError(res, "Themis failed to generate symmetric key")

return string_at(key, key_length.value)
21 changes: 21 additions & 0 deletions src/wrappers/themis/ruby/lib/rbthemis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class CallbacksStruct < FFI::Struct
[:pointer, :pointer, :pointer, :pointer], :int
attach_function :themis_gen_ec_key_pair,
[:pointer, :pointer, :pointer, :pointer], :int
attach_function :themis_gen_sym_key,
[:pointer, :pointer], :int

THEMIS_KEY_INVALID = 0
THEMIS_KEY_RSA_PRIVATE = 1
Expand Down Expand Up @@ -476,6 +478,24 @@ def s_verify(peer_public_key, message)
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
end

def gen_sym_key
key_length = FFI::MemoryPointer.new(:uint)

res = themis_gen_sym_key(nil, key_length)
if res != BUFFER_TOO_SMALL
raise ThemisError, "failed to get symmetric key size: #{res}"
end

key = FFI::MemoryPointer.new(:char, key_length.read_uint)

res = themis_gen_sym_key(key, key_length)
if res != SUCCESS
raise ThemisError, "failed to generate symmetric key: #{res}"
end

return key.get_bytes(0, key_length.read_uint)
end

class Scell
include ThemisCommon
include ThemisImport
Expand Down Expand Up @@ -702,4 +722,5 @@ def result
module_function :Sverify
module_function :s_sign
module_function :s_verify
module_function :gen_sym_key
end
6 changes: 6 additions & 0 deletions src/wrappers/themis/rust/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

The version currently in development.

## New features

- New `SymmetricKey` objects can be used as master keys for `SecureCell`. ([#561])

[#561]: https://github.com/cossacklabs/themis/pull/561

Version 0.12.0 - 2019-09-26
===========================

Expand Down
Loading