56c064 | 2008-07-31 | Martin Stjernholm | | /* -*- c -*-
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
*/
|
c735c0 | 2003-03-18 | Niels Möller | |
#include "global.h"
#include "interpret.h"
#include "svalue.h"
|
675b55 | 2003-11-29 | Martin Nilsson | | #include "array.h"
|
804806 | 2003-12-06 | Martin Nilsson | | #include "operators.h"
|
602fe6 | 2004-02-21 | Martin Nilsson | | #include "threads.h"
|
c735c0 | 2003-03-18 | Niels Möller | |
/* For this_object() */
#include "object.h"
#include "module_support.h"
|
a52eee | 2015-08-02 | Henrik Grubbström (Grubba) | | /* For my_rand() */
#include "stuff.h"
|
c735c0 | 2003-03-18 | Niels Möller | | #include "nettle_config.h"
#ifdef HAVE_LIBNETTLE
|
56c064 | 2008-07-31 | Martin Stjernholm | | DECLARATIONS
|
c735c0 | 2003-03-18 | Niels Möller | | #include "nettle.h"
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | #include <nettle/memxor.h>
|
c735c0 | 2003-03-18 | Niels Möller | | #include <nettle/aes.h>
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | #include <nettle/arctwo.h>
|
8417e5 | 2003-08-24 | Martin Nilsson | | #include <nettle/arcfour.h>
|
85fc8e | 2011-04-21 | Martin Nilsson | | #ifdef HAVE_NETTLE_BLOWFISH_DECRYPT
|
1b3471 | 2003-08-25 | Martin Nilsson | | #include <nettle/blowfish.h>
|
dc4a97 | 2008-07-17 | Martin Stjernholm | | #endif
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_CAMELLIA_H
#include <nettle/camellia.h>
#endif
|
408f68 | 2003-07-29 | Martin Nilsson | | #include <nettle/cast128.h>
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_CHACHA_H
#include <nettle/chacha.h>
#endif
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | #include <nettle/des.h>
#ifdef HAVE_NETTLE_SALSA20_CRYPT
#include <nettle/salsa20.h>
#endif
|
85fc8e | 2011-04-21 | Martin Nilsson | | #ifdef HAVE_NETTLE_SERPENT_DECRYPT
|
408f68 | 2003-07-29 | Martin Nilsson | | #include <nettle/serpent.h>
|
dc4a97 | 2008-07-17 | Martin Stjernholm | | #endif
|
408f68 | 2003-07-29 | Martin Nilsson | | #include <nettle/twofish.h>
|
fc0689 | 2003-11-27 | Martin Nilsson | | #include "idea.h"
|
c735c0 | 2003-03-18 | Niels Möller | |
|
efd5ff | 2013-11-30 | Henrik Grubbström (Grubba) | | #include <nettle/cbc.h>
|
f8b724 | 2015-04-17 | Martin Nilsson | | #include <nettle/ctr.h>
|
efd5ff | 2013-11-30 | Henrik Grubbström (Grubba) | |
|
3add1f | 2003-03-25 | Martin Nilsson | | /*! @module Nettle
*/
|
c735c0 | 2003-03-18 | Niels Möller | |
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | static struct pike_string *nul13_string = NULL;
static struct pike_string *nul16_string = NULL;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | /* Generic callback function for Nettle in case the crypt()
* function in the object isn't a Nettle function.
*/
|
6ef3c1 | 2014-11-06 | Henrik Grubbström (Grubba) | | #ifdef dsa_params_init
/* Nettle 3.0 */
|
64337a | 2014-11-06 | Martin Nilsson | | static void pike_crypt_func(const void *object, pike_nettle_size_t length,
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | uint8_t *dst, const uint8_t *src)
|
6ef3c1 | 2014-11-06 | Henrik Grubbström (Grubba) | | #else
static void pike_crypt_func(void *object, pike_nettle_size_t length,
uint8_t *dst, const uint8_t *src)
#endif
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | {
struct pike_string *str;
push_string(make_shared_binary_string((const char *)src, length));
|
6424ff | 2014-11-06 | Martin Nilsson | | apply((struct object *)object, "crypt", 1);
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | get_all_args("crypt", 1, "%n", &str);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | if (str->len != (ptrdiff_t)length) {
Pike_error("Bad string length %ld returned from crypt()\n",
|
77af4f | 2015-10-14 | Martin Nilsson | | (long)str->len);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(dst, str->str, length);
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | pop_stack();
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
|
c4316a | 2015-04-15 | Henrik Grubbström (Grubba) | | #if !defined(HAVE_MEMXOR3) && !defined(memxor3)
/* Really old versions of nettle don't have memxor3().
*
* Note that prior to Nettle 3.1 memxor3() didn't have a namespace prefix.
*/
|
ceff14 | 2015-03-18 | Henrik Grubbström (Grubba) | | static unsigned char *pike_memxor3(unsigned char *dst, const unsigned char *a,
const unsigned char *b, size_t n)
{
size_t i;
for(i = 0; i < n; i++) {
dst[i] = a[i]^b[i];
}
return dst;
}
#define memxor3(D, A, B, N) pike_memxor3((D), (A), (B), (N))
#endif
|
13670c | 2015-05-25 | Martin Nilsson | | /* Calls Pike_error on errors */
|
662c98 | 2003-11-09 | Niels Möller | | typedef void (*pike_nettle_set_key_func)(void *ctx,
ptrdiff_t length, const char *key,
/* Force means to use key even if it is weak */
int force);
|
c735c0 | 2003-03-18 | Niels Möller | |
|
662c98 | 2003-11-09 | Niels Möller | | struct pike_cipher
{
const char *name;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
662c98 | 2003-11-09 | Niels Möller | | unsigned context_size;
|
fc0689 | 2003-11-27 | Martin Nilsson | |
|
662c98 | 2003-11-09 | Niels Möller | | unsigned block_size;
/* Suggested key size; other sizes are sometimes possible. */
unsigned key_size;
pike_nettle_set_key_func set_encrypt_key;
pike_nettle_set_key_func set_decrypt_key;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func encrypt;
pike_nettle_crypt_func decrypt;
|
662c98 | 2003-11-09 | Niels Möller | | };
#define _PIKE_CIPHER(name, NAME) { \
#name, \
sizeof(struct name##_ctx), \
NAME##_BLOCK_SIZE, \
NAME##_KEY_SIZE, \
pike_##name##_set_encrypt_key, \
pike_##name##_set_decrypt_key, \
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | (pike_nettle_crypt_func) name##_encrypt, \
(pike_nettle_crypt_func) name##_decrypt, \
|
662c98 | 2003-11-09 | Niels Möller | | }
|
c1f5ab | 2003-08-26 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define STREAM_MODE "stream"
#cmod_define BLOCK_MODE "block"
#cmod_define BLOCK16_MODE "block16"
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @class Cipher
|
c735c0 | 2003-03-18 | Niels Möller | | *!
*! Represents information about a cipher algorithm, such as
*! name, key size, and block size.
*/
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | PIKECLASS Cipher
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @decl inherit __builtin.Nettle.Cipher
*/
INHERIT "__builtin.Nettle.Cipher";
|
662c98 | 2003-11-09 | Niels Möller | | CVAR const struct pike_cipher *meta;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | |
DECLARE_STORAGE;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | INIT
{
THIS->meta = NULL;
}
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) name()
|
c735c0 | 2003-03-18 | Niels Möller | | *!
|
127b2f | 2003-03-18 | Niels Möller | | *! @returns
*! A human readable name for the algorithm.
|
c735c0 | 2003-03-18 | Niels Möller | | */
|
5345c9 | 2013-05-19 | Martin Nilsson | | PIKEFUN string(0..255) name()
|
1a2b71 | 2004-02-14 | Martin Nilsson | | optflags OPT_TRY_OPTIMIZE;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | {
if (!THIS->meta)
Pike_error("Cipher not properly initialized.\n");
|
c735c0 | 2003-03-18 | Niels Möller | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | push_text(THIS->meta->name);
}
|
c735c0 | 2003-03-18 | Niels Möller | |
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) key_size()
|
c735c0 | 2003-03-18 | Niels Möller | | *!
|
127b2f | 2003-03-18 | Niels Möller | | *! @returns
*! The recommended key size for the cipher.
|
c735c0 | 2003-03-18 | Niels Möller | | */
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) key_size()
|
1a2b71 | 2004-02-14 | Martin Nilsson | | optflags OPT_TRY_OPTIMIZE;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | {
if (!THIS->meta)
Pike_error("Cipher not properly initialized.\n");
|
c735c0 | 2003-03-18 | Niels Möller | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | push_int(THIS->meta->key_size);
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) block_size()
|
c735c0 | 2003-03-18 | Niels Möller | | *!
|
127b2f | 2003-03-18 | Niels Möller | | *! @returns
|
01a1ba | 2003-12-14 | Martin Nilsson | | *! The block size of the cipher (1 for stream ciphers).
|
c735c0 | 2003-03-18 | Niels Möller | | */
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) block_size()
|
1a2b71 | 2004-02-14 | Martin Nilsson | | optflags OPT_TRY_OPTIMIZE;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | {
if (!THIS->meta)
Pike_error("Cipher not properly initialized.\n");
push_int(THIS->meta->block_size);
}
|
c735c0 | 2003-03-18 | Niels Möller | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @class State
*!
*! Base class for cipher contexts.
*/
PIKECLASS State
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT|PROGRAM_CLEAR_STORAGE;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | {
DOCSTART() @decl inherit Cipher::State
DOCEND()
EXTRA
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* Perform an inherit of the State class (if any) that our parent
* may contain via its inherit of __builtin.Nettle.Hash.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | CVAR pike_nettle_crypt_func crypt;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | CVAR void *ctx;
CVAR int key_size;
|
c735c0 | 2003-03-18 | Niels Möller | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* FIXME: Create should copy state from the other object, if
* provided. */
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
13e2ba | 2014-04-26 | Henrik Grubbström (Grubba) | | #define GET_INFO() ((struct Nettle_Cipher_struct *)parent_storage(1, Nettle_Cipher_program))
|
1b3471 | 2003-08-25 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* Generate a random string of length @[size] on top of the stack. */
static void low_make_key(INT32 size)
{
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text("Crypto.Random");
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | APPLY_MASTER("resolv",1);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) != T_OBJECT)
Pike_error("Failed to resolv Crypto.Random.\n");
push_int(size);
apply(Pike_sp[-2].u.object, "random_string", 1);
stack_swap();
pop_stack();
}
|
c735c0 | 2003-03-18 | Niels Möller | |
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl State set_encrypt_key(string(0..255) key, void|int flags)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *!
*! Initializes the object for encryption. The @[key] memory will be
*! cleared before released.
*!
*! @seealso
*! @[set_decrypt_key], @[crypt]
*/
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | PIKEFUN object set_encrypt_key(string(0..255) key, void|int flags)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | optflags OPT_SIDE_EFFECT;
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | rawtype tFunc(tStr8 tOr(tInt, tVoid), tObjImpl_NETTLE_CIPHER_STATE);
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
|
c735c0 | 2003-03-18 | Niels Möller | | assert(info);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
|
c735c0 | 2003-03-18 | Niels Möller | | if (!THIS->ctx || !info->meta)
|
f1c9f4 | 2003-08-05 | Martin Nilsson | | Pike_error("CipherState not properly initialized.\n");
|
c735c0 | 2003-03-18 | Niels Möller | |
NO_WIDE_STRING(key);
|
bb6493 | 2013-08-09 | Arne Goedeke | | key->flags |= STRING_CLEAR_ON_EXIT;
|
662c98 | 2003-11-09 | Niels Möller | | info->meta->set_encrypt_key(THIS->ctx, key->len, key->str,
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | flags ? flags->u.integer : 0);
|
c1f5ab | 2003-08-26 | Martin Nilsson | |
|
c735c0 | 2003-03-18 | Niels Möller | | THIS->crypt = info->meta->encrypt;
|
1b3471 | 2003-08-25 | Martin Nilsson | | THIS->key_size = key->len;
|
c735c0 | 2003-03-18 | Niels Möller | |
|
2e0ac2 | 2014-03-20 | Henrik Grubbström (Grubba) | | RETURN this_object();
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl State set_decrypt_key(string(0..255) key, void|int flags)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *!
*! Initializes the object for decryption. The @[key] memory will be
*! cleared before released.
*!
*! @seealso
*! @[set_encrypt_key], @[crypt]
*/
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | PIKEFUN object set_decrypt_key(string(0..255) key, void|int flags)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | optflags OPT_SIDE_EFFECT;
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | rawtype tFunc(tStr8 tOr(tInt, tVoid), tObjImpl_NETTLE_CIPHER_STATE);
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
|
c735c0 | 2003-03-18 | Niels Möller | | assert(info);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
c735c0 | 2003-03-18 | Niels Möller | | if (!THIS->ctx || !info->meta)
|
f1c9f4 | 2003-08-05 | Martin Nilsson | | Pike_error("CipherState not properly initialized.\n");
|
c735c0 | 2003-03-18 | Niels Möller | |
NO_WIDE_STRING(key);
|
bb6493 | 2013-08-09 | Arne Goedeke | | key->flags |= STRING_CLEAR_ON_EXIT;
|
662c98 | 2003-11-09 | Niels Möller | | info->meta->set_decrypt_key(THIS->ctx, key->len, key->str,
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | flags ? flags->u.integer : 0);
|
c735c0 | 2003-03-18 | Niels Möller | | THIS->crypt = info->meta->decrypt;
|
1b3471 | 2003-08-25 | Martin Nilsson | | THIS->key_size = key->len;
|
c735c0 | 2003-03-18 | Niels Möller | |
|
2e0ac2 | 2014-03-20 | Henrik Grubbström (Grubba) | | RETURN this_object();
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) make_key()
*!
*! Generate a key by calling @[Crypto.Random.random_string] and
*! initialize this object for encryption with that key.
*!
*! @returns
*! The generated key. The key memory will be cleared before
*! released.
*!
*! @seealso
*! @[set_encrypt_key]
*/
|
5345c9 | 2013-05-19 | Martin Nilsson | | PIKEFUN string(0..255) make_key()
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | optflags OPT_EXTERNAL_DEPEND;
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | assert(info);
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | low_make_key(info->meta->key_size);
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | stack_dup();
Pike_sp[-1].u.string->flags |= STRING_CLEAR_ON_EXIT;
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | apply_current(f_Nettle_Cipher_State_set_encrypt_key_fun_num, 1);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | pop_stack();
}
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) crypt(string(0..255) data)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *!
*! Encrypts or decrypts data, using the current key. Neither the
*! input nor output data is automatically memory scrubbed,
*! unless @[String.secure] has been called on them.
*!
*! @param data
*! For block ciphers, data must be an integral number of blocks.
*!
*! @returns
*! The encrypted or decrypted data.
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) crypt (string(0..255) data)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | optflags OPT_EXTERNAL_DEPEND | OPT_SIDE_EFFECT;
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
|
c735c0 | 2003-03-18 | Niels Möller | | struct pike_string *s;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func crypt;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | void *ctx;
|
c735c0 | 2003-03-18 | Niels Möller | | assert(info);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if (!(ctx = THIS->ctx) || !(crypt = THIS->crypt) || !info->meta)
|
f1c9f4 | 2003-08-05 | Martin Nilsson | | Pike_error("CipherState not properly initialized.\n");
|
c735c0 | 2003-03-18 | Niels Möller | |
NO_WIDE_STRING(data);
|
5040d8 | 2003-11-29 | Martin Nilsson | | if (data->len % info->meta->block_size)
|
f1c9f4 | 2003-08-05 | Martin Nilsson | | Pike_error("Data must be an integral number of blocks.\n");
|
c735c0 | 2003-03-18 | Niels Möller | |
s = begin_shared_string(data->len);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if (data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) {
THREADS_ALLOW();
crypt(ctx, data->len, STR0(s), STR0(data));
THREADS_DISALLOW();
} else {
crypt(ctx, data->len, STR0(s), STR0(data));
}
|
bb6493 | 2013-08-09 | Arne Goedeke | | s = end_shared_string(s);
push_string(s);
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) name(void)
*!
*! @returns
*! A human readable name for the algorithm.
*!
*! @note
*! The default implementation just calls @[Cipher::name()]
*! in the parent.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | apply_external(1, f_Nettle_Cipher_name_fun_num, args);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | }
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) key_size(void)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! The actual key size for this cipher.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) key_size()
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | optflags OPT_TRY_OPTIMIZE;
|
1b3471 | 2003-08-25 | Martin Nilsson | | {
RETURN THIS->key_size;
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) block_size(void)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! The block size for this cipher.
*!
*! @note
*! The default implementation just calls @[Cipher::block_size()]
*! in the parent.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) block_size()
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | optflags OPT_TRY_OPTIMIZE;
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | }
INIT
|
c735c0 | 2003-03-18 | Niels Möller | | {
THIS->ctx = NULL;
THIS->crypt = NULL;
|
68108c | 2003-08-26 | Martin Nilsson | | THIS->key_size = 0;
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | EXIT
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
2d5a56 | 2003-05-08 | Henrik Grubbström (Grubba) | | if (THIS->ctx && Pike_fp->current_object->prog)
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
|
c735c0 | 2003-03-18 | Niels Möller | | assert(info);
assert(info->meta);
memset(THIS->ctx, 0, info->meta->context_size);
}
}
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | }
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @endclass State
*/
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @endclass Cipher
*/
|
c735c0 | 2003-03-18 | Niels Möller | |
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @class BufferedCipher
*!
*! Extends the @[Cipher] class with the @[Buffer]
*! meta cipher. This is in turn inherited by the
*! @[BlockCipher] class, which is the base class
*! for all block ciphers.
*/
PIKECLASS BufferedCipher
{
/* NOTE: MUST be first in the class to simplify access to symbols
* in Cipher!
*/
/*! @decl inherit Cipher
*/
INHERIT Nettle_Cipher;
#define PAD_SSL 0
#define PAD_ISO_10126 1
#define PAD_ANSI_X923 2
#define PAD_PKCS7 3
#define PAD_ZERO 4
#define PAD_TLS 5
/*! @module Buffer
*! Acts as a buffer so that data can be fed to the cipher in blocks
*! that don't correspond to cipher block sizes.
*!
*! @example
*! class Encrypter
*! {
*! protected Crypto.Cipher buffer;
*!
*! void create(string key)
*! {
|
a79716 | 2014-04-30 | Henrik Grubbström (Grubba) | | *! buffer = Crypto.AES.CBC.Buffer();
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *! buffer->set_encrypt_key(key);
*! }
*!
*! string feed(string data)
*! {
*! return buffer->crypt(data);
*! }
*!
*! string drain()
*! {
*! return buffer->pad(Crypto.PAD_PKCS7);
*! }
*! }
*!
*! @seealso
*! @[BlockCipher.CBC], @[BlockCipher16.GCM]
*/
PIKEVAR object(Nettle_BufferedCipher_cq__Buffer) Buffer;
PIKECLASS _Buffer
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit __builtin.Nettle.Cipher
*/
INHERIT "__builtin.Nettle.Cipher";
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
apply_external(1, f_Nettle_Cipher_name_fun_num, args);
push_constant_text(".Buffer");
f_add(2);
}
PIKEFUN int(1..) block_size()
{
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
PIKEFUN int(1..) key_size()
{
apply_external(1, f_Nettle_Cipher_key_size_fun_num, args);
}
PIKEFUN int(0..) iv_size()
{
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
a79716 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @class State
*! Acts as a buffer so that data can be fed to the cipher in blocks
*! that don't correspond to cipher block sizes.
*!
*! @example
*! class Encrypter
*! {
*! protected Crypto.Cipher buffer;
*!
*! void create(string key)
*! {
*! buffer = Crypto.AES.CBC.Buffer();
*! buffer->set_encrypt_key(key);
*! }
*!
*! string feed(string data)
*! {
*! return buffer->crypt(data);
*! }
*!
*! string drain()
*! {
*! return buffer->pad(Crypto.PAD_PKCS7);
*! }
*! }
*!
*! @seealso
*! @[BlockCipher.CBC], @[BlockCipher16.GCM]
*/
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | PIKECLASS State
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT|PROGRAM_CLEAR_STORAGE;
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | {
CVAR struct object *object;
CVAR int block_size;
CVAR unsigned char *backlog;
CVAR int backlog_len;
INIT {
THIS->object = NULL;
THIS->block_size = 0;
THIS->backlog = NULL;
THIS->backlog_len = 0;
}
EXIT
gc_trivial;
{
if(THIS->backlog) {
guaranteed_memset(THIS->backlog, 0, THIS->block_size);
free(THIS->backlog);
THIS->backlog = NULL;
}
if(THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
}
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | /*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *!
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | *! Defaults to creating the State for the cipher implemented
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *! in the parent module.
*/
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
apply_external(2, Nettle_Cipher_State_program_fun_num, 0);
}
/*! @decl void create()
*!
*! Initialize the buffer with the @[Cipher::State] object
*! returned by @[substate_factory()]. This is usually
*! the State for the cipher implemented in the parent module.
*/
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
int block_size;
int f;
exit_Nettle_BufferedCipher_cq__Buffer_State_struct();
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | apply_current(f_Nettle_BufferedCipher_cq__Buffer_State_substate_factory_fun_num,
0);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | |
if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(o, "block_size", 0);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | |
if(TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
block_size = Pike_sp[-1].u.integer;
if ((!block_size) || (block_size > 4096))
Pike_error("Bad block size %d.\n", block_size);
THIS->block_size = block_size;
THIS->backlog = xcalloc(1, block_size);
THIS->backlog_len = 0;
add_ref(THIS->object = o);
}
/*! @decl string(0..255) name()
*! Returns the name of the wrapped cipher with @expr{".Buffer"@}
*! appended.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "name", 0);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | push_constant_text(".Buffer");
f_add(2);
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) block_size()
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *!
*! Get the block size of the contained block crypto.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) block_size()
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) key_size()
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *!
*! Get the key size of the contained block crypto.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) key_size()
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | optflags OPT_EXTERNAL_DEPEND;
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "key_size", args);
}
/*! @decl int(0..) iv_size()
*!
*! Get the iv size of the contained block crypto.
*/
PIKEFUN int(0..) iv_size()
optflags OPT_EXTERNAL_DEPEND;
{
apply(THIS->object, "iv_size", args);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | }
/*! @decl this_program set_encrypt_key(string(0..255) key, @
*! void|int flags)
*!
*! Set the encryption key. The @[key] memory will be cleared before
*! released.
*!
*! @note
*! As a side-effect any buffered data will be cleared.
*/
PIKEFUN object set_encrypt_key(string(0..255) key, void|int flags)
optflags OPT_SIDE_EFFECT;
{
THIS->backlog_len = 0;
key->flags |= STRING_CLEAR_ON_EXIT;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_encrypt_key", args);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | pop_stack();
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, @
*! void|int flags)
*!
*! Set the decryption key. The @[key] memory will be cleared before
*! released.
*!
*! @note
*! As a side-effect any buffered data will be cleared.
*/
PIKEFUN object set_decrypt_key(string(0..255) key, void|int flags)
optflags OPT_SIDE_EFFECT;
{
THIS->backlog_len = 0;
key->flags |= STRING_CLEAR_ON_EXIT;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_decrypt_key", args);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | pop_stack();
push_object(this_object());
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt or decrypt some data.
*!
*! Adds data to be en/decrypted to the buffer. If there's enough
*! data to en/decrypt a block, that will be done, and the result
*! returned. Any unprocessed data will be left in the buffer.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*/
PIKEFUN string(0..255) crypt(string(0..255) data) {
ptrdiff_t strings = 0;
ptrdiff_t soffset = 0;
ptrdiff_t len;
if (THIS->backlog_len) {
if (data->len >= (THIS->block_size - THIS->backlog_len)) {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(THIS->backlog + THIS->backlog_len, data->str,
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | (THIS->block_size - THIS->backlog_len));
soffset += (THIS->block_size - THIS->backlog_len);
THIS->backlog_len = 0;
push_string(make_shared_binary_string((char *)THIS->backlog,
THIS->block_size));
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "crypt", 1);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != T_STRING)
Pike_error("crypt() did not return string\n");
if (Pike_sp[-1].u.string->len != THIS->block_size)
Pike_error("Unexpected string length %ld\n",
|
77af4f | 2015-10-14 | Martin Nilsson | | (long)Pike_sp[-1].u.string->len);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | strings++;
} else {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(THIS->backlog + THIS->backlog_len,
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | data->str, data->len);
THIS->backlog_len += data->len;
pop_n_elems(args);
push_empty_string();
return;
}
}
len = (data->len - soffset);
len -= len % THIS->block_size;
if (len) {
push_string( string_slice( data, soffset, len ) );
soffset += len;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "crypt", 1);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | |
if (TYPEOF(Pike_sp[-1]) != T_STRING)
Pike_error("crypt() did not return string.\n");
if (Pike_sp[-1].u.string->len != len)
Pike_error("crypt() Unexpected string length %ld.\n",
|
77af4f | 2015-10-14 | Martin Nilsson | | (long)Pike_sp[-1].u.string->len);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | |
strings++;
}
if (soffset < data->len) {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(THIS->backlog, data->str + soffset, data->len - soffset);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | THIS->backlog_len = data->len - soffset;
}
if( !strings )
push_empty_string();
else if( strings > 1 )
f_add( strings );
stack_pop_n_elems_keep_top(args);
}
/*! @decl string(0..255) pad(void|int method)
*!
*! Pad and encrypt any data left in the buffer. The output data is
*! not automatically memory scrubbed, unless @[String.secure] is
*! called on the data.
*!
*! @param method
*! The type of padding to apply to the buffer.
*! @int
*! @value Crypto.PAD_ISO_10126
*! Pads according to ISO 10126, which means filling all extra
*! space with random data and putting the size of the
*! non-payload data last.
*! @value Crypto.PAD_TLS
*! @value Crypto.PAD_SSL
|
0c4ea5 | 2015-08-22 | Martin Nilsson | | *! Pads according to @rfc{5246:6.2.3.2@}, meaning that all
*! extra space is filled with the size of the padding. Note
*! that this size has an off by one difference to the other
*! schemas, so 0 means 1 byte of padding.
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *! @value Crypto.PAD_ANSI_X923
*! Pads according to ANSI X.923, which means filling all extra
*! space with zero and putting the size of the non-payload data
*! last.
*! @value Crypto.PAD_PKCS7
|
974d4a | 2015-08-22 | Martin Nilsson | | *! Pads according to PKCS7 / @rfc{3852@}, which means
*! filling all extra space with the size of the extra
*! space.
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *! @value Crypto.PAD_ZERO
*! Fills the extra space with null bytes. To correctly remove
*! the padding the clear text data must not end with a null
*! byte. In that case the data would have to be manually
*! padded/unpadded before/after calling @[crypt()].
*! @endint
*! Defaults to Crypto.PAD_SSL for compatibility reasons.
*!
*! @seealso
*! @[unpad()]
*/
PIKEFUN string(0..255) pad(void|int method) {
ptrdiff_t i;
int m = 0;
int size = THIS->block_size - THIS->backlog_len;
if(method)
{
if(TYPEOF(*method) != PIKE_T_INT)
Pike_error("Bad argument type.\n");
m = method->u.integer;
}
switch(m)
{
case PAD_SSL:
case PAD_TLS:
size--;
break;
case PAD_ZERO:
if( THIS->backlog_len>0 &&
THIS->backlog[THIS->backlog_len-1] == 0 )
Pike_error("Using zero padding on a zero terminated string.\n");
size = 0;
break;
}
for (i = THIS->backlog_len; i < THIS->block_size - 1; i++)
switch(m)
{
default:
Pike_error("Unknown method.\n");
case PAD_SSL:
case PAD_TLS:
/* TLS 1.1 and forward */
THIS->backlog[i] = size;
break;
case PAD_ISO_10126:
/* ISO 10126 */
|
a51d50 | 2015-11-15 | Martin Nilsson | | THIS->backlog[i] = (unsigned char)my_rand(256);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | break;
case PAD_ANSI_X923:
/* ANSI X.923 */
THIS->backlog[i] = 0;
break;
case PAD_PKCS7:
/* PKCS7 / RFC 3852 */
|
77af4f | 2015-10-14 | Martin Nilsson | | THIS->backlog[i] = (unsigned char)size;
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | break;
case PAD_ZERO:
/* Null only */
THIS->backlog[i] = 0;
break;
}
|
77af4f | 2015-10-14 | Martin Nilsson | | THIS->backlog[THIS->block_size - 1] = (unsigned char)size;
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | push_string(make_shared_binary_string((const char *)THIS->backlog, THIS->block_size));
THIS->backlog_len = 0;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "crypt", 1);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | }
/*! @decl string(0..255) unpad(string(0..255) data, void|int method)
*!
*! Decrypt and unpad a block of data. Neither the input or output
*! data is not automatically memory scrubbed, unless
*! @[String.secure] has been called on the data.
*!
*! This performs the reverse operation of @[pad()]. The padding
*! will be verified to be correct, if possible. If not, zero is
*! returned.
*!
*! @param method
*! The type of padding that was applied to the original buffer.
*! @int
*! @value Crypto.PAD_SSL
*! @value Crypto.PAD_TLS
*! @value Crypto.PAD_ISO_10126
*! @value Crypto.PAD_ANSI_X923
*! @value Crypto.PAD_PKCS7
*! @value Crypto.PAD_ZERO
*! @endint
*! Defaults to Crypto.PAD_SSL for compatibility reasons.
*!
*! @seealso
*! @[pad()]
*/
PIKEFUN string(0..255) unpad(string(0..255) str, void|int method) {
ptrdiff_t len, bytes;
int m = 0, i, invalid = 0, padding=0;
len = str->len + THIS->backlog_len;
if( len % THIS->block_size)
Pike_error("Total data size must be integral numbers of blocks.\n");
if( method!=NULL )
{
m = method->u.integer;
pop_stack();
args--;
}
f_Nettle_BufferedCipher_cq__Buffer_State_crypt(1);
if (TYPEOF(Pike_sp[-1]) != T_STRING)
Pike_error("crypt() did not return string.\n");
if (Pike_sp[-1].u.string->len != len)
Pike_error("crypt() Unexpected string length %ld.\n",
|
77af4f | 2015-10-14 | Martin Nilsson | | (long)Pike_sp[-1].u.string->len);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | str = Pike_sp[-1].u.string;
|
8b2ebd | 2014-07-21 | Henrik Grubbström (Grubba) | | bytes = STR0(str)[len - 1];
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | if( m==PAD_SSL || m==PAD_TLS ) bytes++;
/* FIXME: Shouldn't this be supported? */
|
8b2ebd | 2014-07-21 | Henrik Grubbström (Grubba) | | if (bytes > str->len)
Pike_error("Invalid padding (%d > %d)\n", bytes, str->len);
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | |
switch( m )
{
default:
Pike_error("Unknown method.\n");
case PAD_ISO_10126:
case PAD_ZERO:
case PAD_SSL:
break;
case PAD_ANSI_X923:
padding = 0;
goto do_check;
case PAD_TLS:
padding = bytes-1;
goto do_check;
case PAD_PKCS7:
padding = bytes;
do_check:
/* Try to be constant time here. */
|
8b2ebd | 2014-07-21 | Henrik Grubbström (Grubba) | | invalid = 1;
for(i=len-256; i<len-1; i++) {
if (i < 0) i = 0;
if (i == len-bytes) invalid = 0;
invalid |= (STR0(str)[i] ^ padding);
}
|
ef28c4 | 2014-07-22 | Henrik Grubbström (Grubba) | | /* NB: If bytes <= 1 the loop will terminate before the
* case where invalid is reset to zero is reached.
*/
if (bytes <= 1) invalid = 0;
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | break;
}
if( m == PAD_ZERO )
{
int c=THIS->block_size;
while( str->str[len-1]==0 && c>0 )
{
c--;
len--;
}
}
else
len -= bytes;
if (len < 0)
Pike_error("String too short to unpad\n");
add_ref(str);
pop_stack();
push_string(make_shared_binary_string(str->str, len));
free_string(str);
|
8b2ebd | 2014-07-21 | Henrik Grubbström (Grubba) | | if( invalid )
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | {
pop_stack();
push_int(0);
}
}
/*! @decl this_program set_iv(string(0..255) iv)
*! Set the initialization vector to @[iv].
*/
PIKEFUN object set_iv(string(0..255) iv)
optflags OPT_SIDE_EFFECT;
{
apply(THIS->object, "set_iv", args);
args = 1;
RETURN this_object();
}
}
/*! @endclass State
*/
|
a48d7e | 2014-04-30 | Henrik Grubbström (Grubba) | |
/*! @decl State `()()
*!
*! @returns
*! Returns a new @[State] object.
*/
PIKEFUN Nettle_BufferedCipher_cq__Buffer_State `()()
{
apply_current(Nettle_BufferedCipher_cq__Buffer_State_program_fun_num,
args);
}
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | }
/*! @endmodule Buffer
*/
INIT
{
apply_current(Nettle_BufferedCipher_cq__Buffer_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BUFFEREDCIPHER->Buffer = Pike_sp[-1].u.object);
}
pop_stack();
}
}
/*! @endclass BufferedCipher */
#define BUFFEREDCIPHER_CIPHER_INHERIT 1
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @class BlockCipher
*!
*! Base class for all block ciphers.
*!
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | *! Extends the @[BufferedCipher] class with various operating modes.
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | */
PIKECLASS BlockCipher
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | /*! @decl inherit __builtin.Nettle.BlockCipher
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | */
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | INHERIT "__builtin.Nettle.BlockCipher";
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BufferedCipher
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | */
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BufferedCipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @module CBC
*! Implementation of the cipher block chaining mode (CBC).
*!
*! Works as a wrapper for the cipher implemented by overloading
*! the parent class (@[Cipher]).
*!
*! @seealso
*! @[Crypto.CBC], @[GCM]
*/
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | PIKEVAR object(Nettle_BlockCipher_cq__CBC) CBC;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
PIKECLASS _CBC
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BufferedCipher
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | */
|
83fe4f | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BufferedCipher;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_name_fun_num, args);
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | push_constant_text(".CBC");
f_add(2);
}
PIKEFUN int(1..) block_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | }
PIKEFUN int(1..) key_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_key_size_fun_num, args);
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | }
PIKEFUN int(0..) iv_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | }
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
/*! @class State
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
DOCSTART() @decl inherit Cipher::State
DOCEND()
EXTRA
{
/* Perform an inherit of the State class (if any) that our parent
* may contain via its inherit of __builtin.Nettle.Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
PIKEVAR object object
flags ID_PRIVATE|ID_PROTECTED|ID_HIDDEN;
CVAR struct Nettle_Cipher_State_struct *crypt_state;
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | CVAR struct pike_string *iv; /* NB: Not finished. */
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | CVAR INT32 block_size;
CVAR INT32 mode;
EXIT
gc_trivial;
{
if(THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
if(THIS->iv) {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | free_string(THIS->iv);
THIS->iv = NULL;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
}
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | /*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
*!
*! Defaults to creating the State for the cipher implemented
*! in the parent module.
*/
PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(2, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
Nettle_Cipher_State_program_fun_num, 0);
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | }
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl void create()
*!
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | *! Initialize the CBC state with the @[Cipher::State] object
*! returned by @[substate_factory()]. This is usually
*! the State for the cipher implemented in the parent module.
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | */
PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
struct inherit *inh;
unsigned old_block_size = THIS->block_size;
unsigned block_size;
int f;
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | apply_current(f_Nettle_BlockCipher_cq__CBC_State_substate_factory_fun_num,
0);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(o, "block_size", 0);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
if(TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
block_size = Pike_sp[-1].u.integer;
if ((!block_size) || (block_size > 4096))
Pike_error("Bad block size %d.\n", block_size);
if(THIS->iv) {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | free_string(THIS->iv);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | THIS->iv = NULL;
}
THIS->block_size = block_size;
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | THIS->iv = begin_shared_string(block_size);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(STR0(THIS->iv), 0, block_size);
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | THIS->iv->flags |= STRING_CLEAR_ON_EXIT;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
if (THIS->object) free_object(THIS->object);
add_ref(THIS->object = o);
inh = INHERIT_FROM_INT(o->prog, f);
if (inh->prog == Nettle_Cipher_State_program) {
/* crypt() is from Nettle.Cipher.State.
* Check if the context and crypt function are valid.
*/
THIS->crypt_state = (struct Nettle_Cipher_State_struct *)
get_inherit_storage(o, inh - o->prog->inherits);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | } else {
THIS->crypt_state = NULL;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"CBC(x)"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text("CBC(");
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "name", 0);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(")");
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | f_add(3);
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) block_size()
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | *! Returns the block size of the encapsulated cipher.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) block_size()
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) key_size()
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | *! Returns the key size of the encapsulated cipher.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) key_size()
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | optflags OPT_EXTERNAL_DEPEND;
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "key_size", args);
}
/*! @decl int(1..) iv_size()
*! Returns the size for the initialization vector
*/
PIKEFUN int(1..) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
/*! @decl this_program set_encrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for encrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*/
PIKEFUN object set_encrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
assert(THIS->block_size);
THIS->mode = 0;
key->flags |= STRING_CLEAR_ON_EXIT;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_encrypt_key", args);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | pop_stack();
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for decrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*/
PIKEFUN object set_decrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
assert(THIS->block_size);
THIS->mode = 1;
key->flags |= STRING_CLEAR_ON_EXIT;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_decrypt_key", args);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | pop_stack();
push_object(this_object());
}
/*! @decl this_program set_iv(string(0..255) iv)
*!
*! Set the initialization vector to @[iv]. The @[iv] memory will be
*! cleared before released.
*/
PIKEFUN object set_iv(string(0..255) iv)
optflags OPT_SIDE_EFFECT;
{
assert(THIS->iv);
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
if(iv->len != THIS->block_size)
Pike_error("Argument incompatible with cipher block size.\n");
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(STR0(THIS->iv), STR0(iv), THIS->block_size);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | RETURN this_object();
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt/decrypt @[data] and return the result. @[data] must
*! be an integral number of blocks.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*/
PIKEFUN string(0..255) crypt(string(0..255) data)
{
struct pike_string *result;
ONERROR uwp;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | struct pike_string *iv = THIS->iv;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | int block_size = THIS->block_size;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
NO_WIDE_STRING(data);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if(data->len % block_size)
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | Pike_error("Data length not multiple of block size.\n");
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
result = begin_shared_string(data->len);
SET_ONERROR (uwp, do_free_string, result);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | if(THIS->mode == 0) {
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | /* Protect the iv from being freed by a different thread. */
add_ref(iv);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | THREADS_ALLOW();
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | cbc_encrypt(ctx, func, block_size, STR0(iv),
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | data->len, STR0(result), STR0(data));
THREADS_DISALLOW();
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | free_string(iv);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | } else {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | cbc_encrypt(ctx, func, block_size, STR0(iv),
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | data->len, STR0(result), STR0(data));
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
else {
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | /* Protect the iv from being freed by a different thread. */
add_ref(iv);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | THREADS_ALLOW();
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | cbc_decrypt(ctx, func, block_size, STR0(iv),
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | data->len, STR0(result), STR0(data));
THREADS_DISALLOW();
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | free_string(iv);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | } else {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | cbc_decrypt(ctx, func, block_size, STR0(iv),
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | data->len, STR0(result), STR0(data));
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
pop_n_elems(args);
push_string(end_shared_string(result));
UNSET_ONERROR(uwp);
}
}
/*! @endclass State
*/
}
/*! @endmodule CBC
*/
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | /*! @module PCBC
*! Implementation of the propagating cipher block chaining mode (PCBC).
*!
|
920465 | 2014-06-06 | Henrik Grubbström (Grubba) | | *! This mode is also known as plaintext cipher block chaining (from
*! Kerberos v4).
*!
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | *! Works as a wrapper for the cipher implemented by overloading
*! the parent class (@[Cipher]).
*!
*! @seealso
*! @[CBC], @[GCM]
*/
PIKEVAR object(Nettle_BlockCipher_cq__PCBC) PCBC;
PIKECLASS _PCBC
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit _CBC
*/
static int f_pcbc_inh_cbc_state_program_fun_num = -1;
EXTRA
{
low_inherit(Nettle_BlockCipher_cq__CBC_program, 0,
Nettle_BlockCipher_cq__CBC_program_fun_num,
42 + 1,
0, NULL);
f_pcbc_inh_cbc_state_program_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
Nettle_BlockCipher_cq__CBC_State_program_fun_num);
}
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_name_fun_num, args);
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | push_constant_text(".PCBC");
f_add(2);
}
/*! @class State
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
DOCSTART() @decl inherit _CBC::State
DOCEND()
static int f_pcbc_state_inh_cbc_state_crypt_fun_num = -1;
EXTRA
{
low_inherit(Nettle_BlockCipher_cq__CBC_State_program, 0,
f_pcbc_inh_cbc_state_program_fun_num,
42 + 1,
0, NULL);
/* We want to call some of our inherited functions recursively... */
f_pcbc_state_inh_cbc_state_crypt_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
f_Nettle_BlockCipher_cq__CBC_State_crypt_fun_num);
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"PCBC(x)"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
struct Nettle_BlockCipher_cq__CBC_State_struct *cbc_state =
get_inherited_storage(1, Nettle_BlockCipher_cq__CBC_State_program);
push_constant_text("PCBC(");
apply(cbc_state->object, "name", 0);
push_constant_text(")");
f_add(3);
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt/decrypt @[data] and return the result. @[data] must
*! be an integral number of blocks.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*/
PIKEFUN string(0..255) crypt(string(0..255) data)
{
struct Nettle_BlockCipher_cq__CBC_State_struct *cbc_state =
get_inherited_storage(1, Nettle_BlockCipher_cq__CBC_State_program);
struct pike_string *propagated;
ONERROR uwp;
int block_size = cbc_state->block_size;
NO_WIDE_STRING(data);
if(data->len % block_size) {
Pike_error("Data length not multiple of block size.\n");
}
if (!cbc_state->object || !cbc_state->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
if (!data->len) {
return;
}
if (cbc_state->mode == 0) {
propagated = begin_shared_string(data->len);
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | | memcpy(STR0(propagated), STR0(data), block_size);
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | if (data->len > block_size) {
memxor3(STR0(propagated) + block_size, STR0(data) + block_size,
STR0(data), data->len - block_size);
}
pop_stack();
push_string(propagated); /* NB: Not shared! */
apply_current(f_pcbc_state_inh_cbc_state_crypt_fun_num, 1);
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | |
/* Update the iv with the last block of the plaintext. */
memxor(STR0(cbc_state->iv), STR0(data) + data->len - block_size,
block_size);
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | } else {
ptrdiff_t offset;
apply_current(f_pcbc_state_inh_cbc_state_crypt_fun_num, 1);
data = Pike_sp[-1].u.string;
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | | if (data->len == block_size) {
memxor(STR0(cbc_state->iv), STR0(data), block_size);
return;
}
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | propagated = begin_shared_string(data->len);
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | | memcpy(STR0(propagated), STR0(data), block_size);
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | |
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | | for(offset = block_size; offset < data->len; offset += block_size) {
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | memxor3(STR0(propagated) + offset, STR0(data) + offset,
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | | STR0(propagated) + offset - block_size, block_size);
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | }
|
5f4b82 | 2014-06-06 | Henrik Grubbström (Grubba) | | memxor(STR0(cbc_state->iv),
STR0(propagated) + offset - block_size, block_size);
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | |
pop_stack();
push_string(end_shared_string(propagated));
}
}
}
/*! @endclass State
*/
}
/*! @endmodule PCBC
*/
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | /*! @module CFB
*! Implementation of Cipher Feed-Back mode (CFB).
*!
*! @seealso
*! @[CBC], @[GCM]
*/
PIKEVAR object(Nettle_Cipher) CFB;
PIKECLASS _CFB
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit BufferedCipher
*/
INHERIT Nettle_BufferedCipher;
/*! @decl string(0..255) name()
*! Returns the base cipher name appended with the string @expr{".CFB"@}.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".CFB");
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | f_add(2);
}
PIKEFUN int(1..) block_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
PIKEFUN int(1..) key_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_key_size_fun_num, args);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
PIKEFUN int(0..) iv_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
/*! @class State
*!
*! The state for a CFB instance.
*/
PIKECLASS State
program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT;
{
DOCSTART() @decl inherit BufferedCipher::State
DOCEND()
EXTRA
{
/* Perform an inherit of the State class (if any) that our parent
* may contain via its inherit of __builtin.Nettle.Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
PIKEVAR object object
flags ID_PRIVATE|ID_PROTECTED|ID_HIDDEN;
CVAR struct Nettle_Cipher_State_struct *crypt_state;
CVAR struct pike_string *iv; /* NB: Not finished. */
CVAR INT32 block_size;
CVAR INT32 mode;
EXIT
gc_trivial;
{
if (THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
if (THIS->iv) {
free_string(THIS->iv);
THIS->iv = NULL;
}
}
/*! @decl object `obj()
*!
*! Getter for the wrapped cipher algorithm.
*/
PIKEFUN object `obj()
{
if (THIS->object) {
ref_push_object(THIS->object);
} else {
push_int(0);
}
}
/*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
*!
*! Defaults to creating the State for the cipher implemented
*! in the parent module.
*/
PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(2, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
Nettle_Cipher_State_program_fun_num, 0);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
/*! @decl void create()
*!
*! Initialize the CFB state with the @[Cipher::State] object
*! returned by @[substate_factory()]. This is usually
*! the State for the cipher implemented in the parent module.
*/
PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
struct inherit *inh;
int old_block_size = THIS->block_size;
int block_size;
int f;
if (THIS->object) free_object(THIS->object);
THIS->object = NULL;
THIS->crypt_state = NULL;
apply_current(f_Nettle_BlockCipher_cq__CFB_State_substate_factory_fun_num,
0);
if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
apply(o, "block_size", 0);
if(TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
block_size = Pike_sp[-1].u.integer;
|
d69c23 | 2014-10-23 | Arne Goedeke | | if ((block_size <= 0) || (block_size > 4096))
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | Pike_error("Bad block size %d.\n", block_size);
inh = INHERIT_FROM_INT(o->prog, f);
if (inh->prog == Nettle_Cipher_State_program) {
/* crypt() is from Nettle.Cipher.State.
* Check if the context and crypt function are valid.
*/
THIS->crypt_state = (struct Nettle_Cipher_State_struct *)
get_inherit_storage(o, inh - o->prog->inherits);
}
if(THIS->iv) {
free_string(THIS->iv);
THIS->iv = NULL;
}
THIS->iv = begin_shared_string(block_size);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(STR0(THIS->iv), 0, block_size);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | THIS->iv->flags |= STRING_CLEAR_ON_EXIT;
THIS->block_size = block_size;
THIS->mode = 0;
add_ref(THIS->object = o);
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"CFB(x)"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text("CFB(");
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | apply(THIS->object, "name", 0);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(")");
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | f_add(3);
}
/*! @decl int(1..) block_size()
*! Returns the block size of the encapsulated cipher.
*/
PIKEFUN int(1..) block_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
/*! @decl int(1..) iv_size()
*! Returns the size for the initialization vector
*/
PIKEFUN int(1..) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
/*! @decl int(1..) key_size()
*! Returns the key size of the encapsulated cipher.
*/
PIKEFUN int(1..) key_size()
optflags OPT_EXTERNAL_DEPEND;
{
apply(THIS->object, "key_size", args);
}
/*! @decl this_program set_encrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for encrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_decrypt_key()], @[set_iv()]
*/
PIKEFUN object set_encrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
apply(THIS->object, "set_encrypt_key", args);
pop_stack();
THIS->mode = 0;
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for decrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_encrypt_key()], @[set_iv()]
*/
PIKEFUN object set_decrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
/* NOTE: CFB always uses the encryption function
* of the underlying cipher!
*/
apply(THIS->object, "set_encrypt_key", args);
pop_stack();
THIS->mode = 1;
push_object(this_object());
}
/*! @decl this_program set_iv(string(0..255) iv)
*!
*! Set the initialization vector to @[iv]. The @[iv] memory will be
*! cleared before released.
*!
*! @note
*! @[iv] must have the length reported by @[iv_size()].
*!
*! @seealso
*! @[set_encrypt_key()], @[set_decrypt_key()].
*/
PIKEFUN object set_iv(string(0..255) iv)
optflags OPT_SIDE_EFFECT;
{
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
if(iv->len != THIS->block_size)
Pike_error("Argument incompatible with cipher block size.\n");
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(STR0(THIS->iv), STR0(iv), THIS->block_size);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | RETURN this_object();
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt/decrypt @[data] and return the result. @[data] must
*! be an integral number of blocks.
*!
*! The length of @[data] MUST be a multiple of the block size
*! for all calls except the last.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*!
*! @seealso
*! @[update()], @[digest()]
*/
PIKEFUN string(0..255) crypt(string(0..255) data)
{
struct pike_string *result;
ONERROR uwp;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
struct pike_string *iv = THIS->iv;
|
0695b4 | 2014-11-05 | Martin Nilsson | | unsigned block_size = (unsigned)THIS->block_size;
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | |
NO_WIDE_STRING(data);
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
if (!data->len) return;
result = begin_shared_string(data->len);
SET_ONERROR (uwp, do_free_string, result);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
if (!THIS->mode) {
/* Encryption. */
const uint8_t *prev = STR0(iv);
uint8_t *src = STR0(data);
uint8_t *dst = STR0(result);
pike_nettle_size_t bytes = data->len;
if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
/* Protect the iv from being freed by a different thread. */
add_ref(iv);
THREADS_ALLOW();
|
2a1708 | 2014-06-13 | Henrik Grubbström (Grubba) | | while (bytes >= block_size) {
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | func(ctx, block_size, STR0(iv), prev);
memxor3(dst, STR0(iv), src, block_size);
prev = dst;
dst += block_size;
src += block_size;
bytes -= block_size;
}
|
2a1708 | 2014-06-13 | Henrik Grubbström (Grubba) | | if (!bytes) {
memcpy(STR0(iv), dst - block_size, block_size);
} else {
/* Trailer partial block. */
func(ctx, block_size, STR0(iv), prev);
memxor3(dst, STR0(iv), src, bytes);
memcpy(STR0(iv), dst, bytes);
}
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | THREADS_DISALLOW();
free_string(iv);
} else {
|
2a1708 | 2014-06-13 | Henrik Grubbström (Grubba) | | while (bytes >= block_size) {
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | func(ctx, block_size, STR0(iv), prev);
memxor3(dst, STR0(iv), src, block_size);
prev = dst;
dst += block_size;
src += block_size;
bytes -= block_size;
}
|
2a1708 | 2014-06-13 | Henrik Grubbström (Grubba) | | if (!bytes) {
memcpy(STR0(iv), dst - block_size, block_size);
} else {
/* Trailer partial block. */
func(ctx, block_size, STR0(iv), prev);
memxor3(dst, STR0(iv), src, bytes);
memcpy(STR0(iv), dst, bytes);
}
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
} else {
/* Decryption. */
|
0695b4 | 2014-11-05 | Martin Nilsson | | unsigned trailer_len = data->len % block_size;
unsigned blocked_len = data->len - trailer_len;
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
/* Protect the iv from being freed by a different thread. */
add_ref(iv);
THREADS_ALLOW();
|
2a1708 | 2014-06-13 | Henrik Grubbström (Grubba) | | if (blocked_len) {
memcpy(STR0(result), STR0(iv), block_size);
if (blocked_len > block_size) {
memcpy(STR0(result) + block_size, STR0(data),
blocked_len - block_size);
}
func(ctx, blocked_len, STR0(result), STR0(result));
memxor(STR0(result), STR0(data), blocked_len);
memcpy(STR0(iv), STR0(data) + blocked_len - block_size,
block_size);
}
if (trailer_len) {
func(ctx, block_size, STR0(iv), STR0(iv));
memxor3(STR0(result) + blocked_len, STR0(data) + blocked_len,
STR0(iv), trailer_len);
memcpy(STR0(iv), STR0(data) + blocked_len, trailer_len);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
THREADS_DISALLOW();
free_string(iv);
} else {
|
2a1708 | 2014-06-13 | Henrik Grubbström (Grubba) | | if (blocked_len) {
memcpy(STR0(result), STR0(iv), block_size);
if (blocked_len > block_size) {
memcpy(STR0(result) + block_size, STR0(data),
blocked_len - block_size);
}
func(ctx, blocked_len, STR0(result), STR0(result));
memxor(STR0(result), STR0(data), blocked_len);
memcpy(STR0(iv), STR0(data) + blocked_len - block_size,
block_size);
}
if (trailer_len) {
func(ctx, block_size, STR0(iv), STR0(iv));
memxor3(STR0(result) + blocked_len, STR0(data) + blocked_len,
STR0(iv), trailer_len);
memcpy(STR0(iv), STR0(data) + blocked_len, trailer_len);
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | }
}
}
pop_n_elems(args);
push_string(end_shared_string(result));
UNSET_ONERROR(uwp);
}
}
/*! @endclass
*/
/*! @decl State `()()
*!
*! @returns
*! Returns a new @[State] object.
*/
PIKEFUN Nettle_Cipher_State `()()
{
apply_current(Nettle_BlockCipher_cq__CFB_State_program_fun_num, args);
}
}
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | /*! @endmodule CFB
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | */
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @module CTR
*! Implementation of Counter Mode (CTR).
*!
*! This cipher mode works like a stream cipher with
*! a block size >= 1. This means that the same key
*! and initialization vector (aka counter) should
*! never be reused, since a simple xor would reveal
*! information about the plain text. It also means
*! that it should never be used without a suiteable
*! Message Authentication Code (MAC).
*!
*! @seealso
*! @[CBC], @[GCM], @[Buffer]
*/
PIKEVAR object(Nettle_Cipher) CTR;
PIKECLASS _CTR
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit __builtin.Nettle.Cipher
*/
INHERIT "__builtin.Nettle.Cipher";
/*! @decl string(0..255) name()
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | *! Returns the base cipher name appended with the string @expr{".CTR"@}.
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | */
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".CTR");
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | f_add(2);
}
PIKEFUN int(1..) block_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | }
PIKEFUN int(1..) key_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_key_size_fun_num, args);
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | }
PIKEFUN int(0..) iv_size()
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
/*! @class State
*!
*! The state for a CTR instance.
*/
PIKECLASS State
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT|PROGRAM_CLEAR_STORAGE;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | {
DOCSTART() @decl inherit Cipher::State
DOCEND()
EXTRA
{
/* Perform an inherit of the State class (if any) that our parent
* may contain via its inherit of __builtin.Nettle.Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
PIKEVAR object object
flags ID_PRIVATE|ID_PROTECTED|ID_HIDDEN;
CVAR struct Nettle_Cipher_State_struct *crypt_state;
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | CVAR struct pike_string *iv; /* NB: Not finished. */
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | CVAR INT32 block_size;
EXIT
gc_trivial;
{
if (THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | if (THIS->iv) {
free_string(THIS->iv);
THIS->iv = NULL;
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
/*! @decl object `obj()
*!
*! Getter for the wrapped cipher algorithm.
*/
PIKEFUN object `obj()
{
if (THIS->object) {
ref_push_object(THIS->object);
} else {
push_int(0);
}
}
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | /*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
*!
*! Defaults to creating the State for the cipher implemented
*! in the parent module.
*/
PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | apply_external(2, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
Nettle_Cipher_State_program_fun_num, 0);
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | }
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @decl void create()
*!
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | *! Initialize the CTR state with the @[Cipher::State] object
*! returned by @[substate_factory()]. This is usually
*! the State for the cipher implemented in the parent module.
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | */
PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
struct inherit *inh;
int old_block_size = THIS->block_size;
int block_size;
int f;
if (THIS->object) free_object(THIS->object);
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | THIS->object = NULL;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | THIS->crypt_state = NULL;
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | apply_current(f_Nettle_BlockCipher_cq__CTR_State_substate_factory_fun_num,
0);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(o, "block_size", 0);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
if(TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
block_size = Pike_sp[-1].u.integer;
if ((!block_size) || (block_size > 4096))
Pike_error("Bad block size %d.\n", block_size);
inh = INHERIT_FROM_INT(o->prog, f);
if (inh->prog == Nettle_Cipher_State_program) {
/* crypt() is from Nettle.Cipher.State.
* Check if the context and crypt function are valid.
*/
THIS->crypt_state = (struct Nettle_Cipher_State_struct *)
get_inherit_storage(o, inh - o->prog->inherits);
}
if(THIS->iv) {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | free_string(THIS->iv);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | THIS->iv = NULL;
}
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | THIS->iv = begin_shared_string(block_size);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(STR0(THIS->iv), 0, block_size);
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | THIS->iv->flags |= STRING_CLEAR_ON_EXIT;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
THIS->block_size = block_size;
add_ref(THIS->object = o);
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"CTR(x)"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text("CTR(");
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "name", 0);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(")");
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | f_add(3);
}
/*! @decl int(1..) block_size()
*! Returns the block size of the encapsulated cipher.
*/
PIKEFUN int(1..) block_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
/*! @decl int(1..) iv_size()
*! Returns the size for the initialization vector
*/
PIKEFUN int(1..) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) key_size()
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | *! Returns the key size of the encapsulated cipher.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) key_size()
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | optflags OPT_EXTERNAL_DEPEND;
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "key_size", args);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
/*! @decl this_program set_encrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for encrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_decrypt_key()], @[set_iv()]
*/
PIKEFUN object set_encrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_encrypt_key", args);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | pop_stack();
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for decrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_encrypt_key()], @[set_iv()]
*/
PIKEFUN object set_decrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
/* NOTE: CTR always uses the encryption function
* of the underlying cipher!
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_encrypt_key", args);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | pop_stack();
push_object(this_object());
}
/*! @decl this_program set_iv(string(0..255) iv)
*!
*! Set the initialization vector to @[iv]. The @[iv] memory will be
*! cleared before released.
*!
*! @note
*! @[iv] must have the length reported by @[iv_size()].
*!
*! @seealso
*! @[set_encrypt_key()], @[set_decrypt_key()].
*/
PIKEFUN object set_iv(string(0..255) iv)
optflags OPT_SIDE_EFFECT;
{
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
if(iv->len != THIS->block_size)
Pike_error("Argument incompatible with cipher block size.\n");
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(STR0(THIS->iv), STR0(iv), THIS->block_size);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | RETURN this_object();
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt/decrypt @[data] and return the result. @[data] must
*! be an integral number of blocks.
*!
*! The length of @[data] MUST be a multiple of the block size
*! for all calls except the last.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*!
*! @seealso
*! @[update()], @[digest()]
*/
PIKEFUN string(0..255) crypt(string(0..255) data)
{
struct pike_string *result;
ONERROR uwp;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | struct pike_string *iv = THIS->iv;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | int block_size = THIS->block_size;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
NO_WIDE_STRING(data);
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
result = begin_shared_string(data->len);
SET_ONERROR (uwp, do_free_string, result);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | /* Protect the iv from being freed by a different thread. */
add_ref(iv);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | THREADS_ALLOW();
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | ctr_crypt(ctx, func, block_size, STR0(iv),
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | data->len, STR0(result), STR0(data));
THREADS_DISALLOW();
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | free_string(iv);
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | } else {
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | ctr_crypt(ctx, func, block_size, STR0(iv),
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | data->len, STR0(result), STR0(data));
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
pop_n_elems(args);
push_string(end_shared_string(result));
UNSET_ONERROR(uwp);
}
}
/*! @endclass
*/
/*! @decl State `()()
*!
*! @returns
*! Returns a new @[State] object.
*/
PIKEFUN Nettle_Cipher_State `()()
{
apply_current(Nettle_BlockCipher_cq__CTR_State_program_fun_num, args);
}
}
/*! @endmodule CTR
*/
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | /*! @module OFB
*! Implementation of Output Feed-Back mode (OFB).
*!
*! This cipher mode works like a stream cipher with
*! a block size >= 1. This means that the same key
*! and initialization vector (aka counter) should
*! never be reused, since a simple xor would reveal
*! information about the plain text. It also means
*! that it should never be used without a suiteable
*! Message Authentication Code (MAC).
*!
*! @seealso
*! @[CFB], @[CBC], @[CTR], @[GCM]
*/
PIKEVAR object(Nettle_Cipher) OFB;
PIKECLASS _OFB
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit BufferedCipher
*/
INHERIT Nettle_BufferedCipher;
/*! @decl string(0..255) name()
*! Returns the base cipher name appended with the string @expr{".OFB"@}.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".OFB");
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | f_add(2);
}
PIKEFUN int(1..) block_size()
{
apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
}
PIKEFUN int(1..) key_size()
{
apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_key_size_fun_num, args);
}
PIKEFUN int(0..) iv_size()
{
apply_external(1, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
f_Nettle_Cipher_block_size_fun_num, args);
}
/*! @class State
*!
*! The state for a OFB instance.
*/
PIKECLASS State
program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT;
{
DOCSTART() @decl inherit BufferedCipher::State
DOCEND()
EXTRA
{
/* Perform an inherit of the State class (if any) that our parent
* may contain via its inherit of __builtin.Nettle.Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
PIKEVAR object object
flags ID_PRIVATE|ID_PROTECTED|ID_HIDDEN;
CVAR struct Nettle_Cipher_State_struct *crypt_state;
CVAR struct pike_string *iv; /* NB: Not finished. */
CVAR INT32 block_size;
EXIT
gc_trivial;
{
if (THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
if (THIS->iv) {
free_string(THIS->iv);
THIS->iv = NULL;
}
}
/*! @decl object `obj()
*!
*! Getter for the wrapped cipher algorithm.
*/
PIKEFUN object `obj()
{
if (THIS->object) {
ref_push_object(THIS->object);
} else {
push_int(0);
}
}
/*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
*!
*! Defaults to creating the State for the cipher implemented
*! in the parent module.
*/
PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
apply_external(2, Nettle_BlockCipher_Nettle_BufferedCipher_inh_offset +
Nettle_Cipher_State_program_fun_num, 0);
}
/*! @decl void create()
*!
*! Initialize the OFB state with the @[Cipher::State] object
*! returned by @[substate_factory()]. This is usually
*! the State for the cipher implemented in the parent module.
*/
PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
struct inherit *inh;
int old_block_size = THIS->block_size;
int block_size;
int f;
if (THIS->object) free_object(THIS->object);
THIS->object = NULL;
THIS->crypt_state = NULL;
apply_current(f_Nettle_BlockCipher_cq__OFB_State_substate_factory_fun_num,
0);
if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
apply(o, "block_size", 0);
if(TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
block_size = Pike_sp[-1].u.integer;
if ((!block_size) || (block_size > 4096))
Pike_error("Bad block size %d.\n", block_size);
inh = INHERIT_FROM_INT(o->prog, f);
if (inh->prog == Nettle_Cipher_State_program) {
/* crypt() is from Nettle.Cipher.State.
* Check if the context and crypt function are valid.
*/
THIS->crypt_state = (struct Nettle_Cipher_State_struct *)
get_inherit_storage(o, inh - o->prog->inherits);
}
if(THIS->iv) {
free_string(THIS->iv);
THIS->iv = NULL;
}
THIS->iv = begin_shared_string(block_size);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(STR0(THIS->iv), 0, block_size);
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | THIS->iv->flags |= STRING_CLEAR_ON_EXIT;
THIS->block_size = block_size;
add_ref(THIS->object = o);
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"OFB(x)"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text("OFB(");
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | apply(THIS->object, "name", 0);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(")");
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | f_add(3);
}
/*! @decl int(1..) block_size()
*! Returns the block size of the encapsulated cipher.
*/
PIKEFUN int(1..) block_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
/*! @decl int(1..) iv_size()
*! Returns the size for the initialization vector
*/
PIKEFUN int(1..) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN THIS->block_size;
}
/*! @decl int(1..) key_size()
*! Returns the key size of the encapsulated cipher.
*/
PIKEFUN int(1..) key_size()
optflags OPT_EXTERNAL_DEPEND;
{
apply(THIS->object, "key_size", args);
}
/*! @decl this_program set_encrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for encrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_decrypt_key()], @[set_iv()]
*/
PIKEFUN object set_encrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
apply(THIS->object, "set_encrypt_key", args);
pop_stack();
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for decrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_encrypt_key()], @[set_iv()]
*/
PIKEFUN object set_decrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
/* NOTE: OFB always uses the encryption function
* of the underlying cipher!
*/
apply(THIS->object, "set_encrypt_key", args);
pop_stack();
push_object(this_object());
}
/*! @decl this_program set_iv(string(0..255) iv)
*!
*! Set the initialization vector to @[iv]. The @[iv] memory will be
*! cleared before released.
*!
*! @note
*! @[iv] must have the length reported by @[iv_size()].
*!
*! @seealso
*! @[set_encrypt_key()], @[set_decrypt_key()].
*/
PIKEFUN object set_iv(string(0..255) iv)
optflags OPT_SIDE_EFFECT;
{
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
if(iv->len != THIS->block_size)
Pike_error("Argument incompatible with cipher block size.\n");
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(STR0(THIS->iv), STR0(iv), THIS->block_size);
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | RETURN this_object();
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt/decrypt @[data] and return the result. @[data] must
*! be an integral number of blocks.
*!
*! The length of @[data] MUST be a multiple of the block size
*! for all calls except the last.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*!
*! @seealso
*! @[update()], @[digest()]
*/
PIKEFUN string(0..255) crypt(string(0..255) data)
{
struct pike_string *result;
ONERROR uwp;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
struct pike_string *iv = THIS->iv;
|
0695b4 | 2014-11-05 | Martin Nilsson | | unsigned block_size = (unsigned)THIS->block_size;
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | uint8_t *src;
uint8_t *dst;
pike_nettle_size_t bytes;
NO_WIDE_STRING(data);
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
if (!(bytes = data->len)) return;
result = begin_shared_string(data->len);
SET_ONERROR (uwp, do_free_string, result);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
src = STR0(data);
dst = STR0(result);
if ((bytes >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
/* Protect the iv from being freed by a different thread. */
add_ref(iv);
THREADS_ALLOW();
while (bytes >= block_size) {
func(ctx, block_size, STR0(iv), STR0(iv));
memxor3(dst, STR0(iv), src, block_size);
dst += block_size;
src += block_size;
bytes -= block_size;
}
if (bytes) {
func(ctx, block_size, STR0(iv), STR0(iv));
memxor3(dst, STR0(iv), src, bytes);
}
THREADS_DISALLOW();
free_string(iv);
} else {
while (bytes >= block_size) {
func(ctx, block_size, STR0(iv), STR0(iv));
memxor3(dst, STR0(iv), src, block_size);
dst += block_size;
src += block_size;
bytes -= block_size;
}
if (bytes) {
func(ctx, block_size, STR0(iv), STR0(iv));
memxor3(dst, STR0(iv), src, bytes);
}
}
pop_n_elems(args);
push_string(end_shared_string(result));
UNSET_ONERROR(uwp);
}
}
/*! @endclass
*/
/*! @decl State `()()
*!
*! @returns
*! Returns a new @[State] object.
*/
PIKEFUN Nettle_Cipher_State `()()
{
apply_current(Nettle_BlockCipher_cq__OFB_State_program_fun_num, args);
}
}
/*! @endmodule OFB
*/
/* NB: Declare the storage explicitly to avoid having it declared
* inside the #ifdef above.
*/
DECLARE_STORAGE;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | INIT
{
apply_current(Nettle_BlockCipher_cq__CBC_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER->CBC = Pike_sp[-1].u.object);
}
pop_stack();
|
2ce282 | 2014-06-02 | Henrik Grubbström (Grubba) | | apply_current(Nettle_BlockCipher_cq__PCBC_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER->PCBC = Pike_sp[-1].u.object);
}
pop_stack();
|
8ea8d5 | 2014-06-07 | Henrik Grubbström (Grubba) | | apply_current(Nettle_BlockCipher_cq__CFB_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER->CFB = Pike_sp[-1].u.object);
}
pop_stack();
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | apply_current(Nettle_BlockCipher_cq__CTR_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER->CTR = Pike_sp[-1].u.object);
}
pop_stack();
|
b631ad | 2014-06-15 | Henrik Grubbström (Grubba) | | apply_current(Nettle_BlockCipher_cq__OFB_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER->OFB = Pike_sp[-1].u.object);
}
pop_stack();
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
}
/*! @endclass BlockCipher
*/
|
62a8ee | 2014-06-14 | Henrik Grubbström (Grubba) | | #define BLOCKCIPHER_CIPHER_INHERIT (BUFFEREDCIPHER_CIPHER_INHERIT + \
Nettle_BlockCipher_Nettle_BufferedCipher_inh_num)
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
/*! @class BlockCipher16
*!
*! This is the @[BlockCipher] class extended with algorithms
*! that require a block size of @expr{16@} bytes.
*!
*! @seealso
*! @[Cipher], @[BlockCipher], @[BufferedCipher], @[GCM]
*/
PIKECLASS BlockCipher16
{
/* NOTE: MUST be first in the class to simplify access to symbols
* in Cipher!
*/
/*! @decl inherit BlockCipher
*/
INHERIT Nettle_BlockCipher;
|
7901d2 | 2014-05-07 | Tobias S. Josefowitz | | #ifdef HAVE_NETTLE_GCM_H
PIKEVAR object(Nettle_AEAD) GCM;
#endif
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @module CCM
*!
*! Implementation of the Counter with Cipher Block Chaining
|
1d65ab | 2014-06-08 | Henrik Grubbström (Grubba) | | *! Message Authentication Code mode (CCM).
*!
*! Works as a wrapper for the cipher implemented by overloading
*! the parent class (@[BlockCipher16]).
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | *!
*! This is a so-called authenticated encryption with associated data
*! (AEAD) algorithm, and in addition to encryption also provides
*! message digests.
*!
*! The operation of CCM is specified in
*! NIST Special Publication 800-38C.
*!
*! @note
*! This mode of operation is not suited for streaming operation,
*! as the sizes of the associated data and payload data need to
*! be known for the CBC-MAC operation to start. Currently this
*! means that the associated data and payload data are buffered
*! until @[State()->digest()] is called.
*!
*! @seealso
*! @[CCM8], @[CBC], @[GCM], @[CTR]
*/
PIKEVAR object(Nettle_AEAD) CCM;
PIKECLASS _CCM
|
1d65ab | 2014-06-08 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | {
/*! @decl inherit __builtin.Nettle.AEAD
*/
INHERIT "__builtin.Nettle.AEAD";
/*! @decl inherit BlockCipher::CTR
*/
EXTRA
{
/* Perform an inherit if the _CTR class that our parent contains
* via its inherit of BlockCipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent__CTR_fun_num =
really_low_find_shared_string_identifier(MK_STRING("_CTR"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent__CTR_fun_num >= 0) {
struct program *parent__CTR_prog =
low_program_from_function(parent_obj, parent__CTR_fun_num);
if (parent__CTR_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent__CTR_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent__CTR_fun_num);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | low_inherit(parent__CTR_prog, 0,
parent__CTR_fun_num,
1 + 42, 0, NULL);
}
}
}
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | /*! @decl string(8bit) name()
*! Returns the name of the base cipher with @expr{".CCM"@} appended.
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | */
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | {
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | apply_external(1, f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".CCM");
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | f_add(2);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
/*! @decl int(4..16) digest_size()
*! Default digest size.
*!
*! @returns
*! Returns @expr{16@}, but overloading via inherit is supported,
*! and may return any even number in the range @expr{[4..16]@}.
*!
*! @note
*! Note that the digest length is folded into the digest, so
*! it doesn't simply imply a truncation.
*/
PIKEFUN int(4..16) digest_size()
{
push_int(16);
}
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) block_size()
{
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
PIKEFUN int(1..) key_size()
{
apply_external(1, f_Nettle_Cipher_key_size_fun_num, args);
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) iv_size()
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | {
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @class State
*/
PIKECLASS State
|
1d65ab | 2014-06-08 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | {
/*! @decl inherit CTR::State
*/
static int ccm_state_inh_ctr_state_create_fun_num = -1;
static int ccm_state_inh_ctr_state_crypt_fun_num = -1;
static int ccm_state_inh_ctr_state_set_encrypt_key_fun_num = -1;
static int ccm_state_inh_ctr_state_set_decrypt_key_fun_num = -1;
EXTRA
{
/* Perform an inherit of the _CTR.State class that our parent
* contains via its inherit of _CTR.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
/* We want to call some of our inherited functions recursively... */
ccm_state_inh_ctr_state_create_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
f_Nettle_BlockCipher_cq__CTR_State_create_fun_num);
ccm_state_inh_ctr_state_crypt_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
f_Nettle_BlockCipher_cq__CTR_State_crypt_fun_num);
ccm_state_inh_ctr_state_set_encrypt_key_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
f_Nettle_BlockCipher_cq__CTR_State_set_encrypt_key_fun_num);
ccm_state_inh_ctr_state_set_decrypt_key_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
f_Nettle_BlockCipher_cq__CTR_State_set_decrypt_key_fun_num);
}
CVAR int decrypt_mode;
PIKEVAR string(8bit) mac_mask flags ID_PRIVATE;
PIKEVAR string(8bit) nonce flags ID_PROTECTED;
CVAR struct string_builder abuf;
CVAR struct string_builder pbuf;
CVAR struct Nettle_BlockCipher_cq__CTR_State_struct *ctr;
INIT
{
init_string_builder(&THIS->abuf, 0);
init_string_builder(&THIS->pbuf, 0);
ASSIGN_CURRENT_STORAGE(THIS->ctr,
struct Nettle_BlockCipher_cq__CTR_State_struct,
1, Nettle_BlockCipher_cq__CTR_State_program);
}
EXIT
{
THIS->ctr = NULL;
free_string_builder(&THIS->abuf);
free_string_builder(&THIS->pbuf);
}
/*! @decl void create()
*/
PIKEFUN void create()
flags ID_PROTECTED;
{
apply_current(ccm_state_inh_ctr_state_create_fun_num, args);
pop_stack();
if (THIS->ctr->block_size != 16) {
Pike_error("Invalid block cipher for CCM: %d.\n",
THIS->ctr->block_size);
}
reset_string_builder(&THIS->abuf);
reset_string_builder(&THIS->pbuf);
if (THIS->nonce) free_string(THIS->nonce);
THIS->nonce = NULL;
}
PIKEFUN string(8bit) name()
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->ctr->object, "name", args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".CCM");
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | f_add(2);
}
PIKEFUN object(Nettle_AEAD_State) set_encrypt_key(string(8bit) key,
int|void flags)
{
reset_string_builder(&THIS->abuf);
reset_string_builder(&THIS->pbuf);
THIS->decrypt_mode = 0;
apply_current(ccm_state_inh_ctr_state_set_encrypt_key_fun_num, args);
}
PIKEFUN object(Nettle_AEAD_State) set_decrypt_key(string(8bit) key,
int|void flags)
{
reset_string_builder(&THIS->abuf);
reset_string_builder(&THIS->pbuf);
THIS->decrypt_mode = 1;
apply_current(ccm_state_inh_ctr_state_set_decrypt_key_fun_num, args);
}
PIKEFUN object(Nettle_AEAD_State) set_iv(string(8bit) iv)
{
int iv_len = iv->len;
uint8_t *ctr_iv;
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
reset_string_builder(&THIS->abuf);
reset_string_builder(&THIS->pbuf);
if (iv_len < 7) {
Pike_error("Too short nonce for CCM. Must be at least 7 bytes.\n");
}
if (THIS->nonce) {
free_string(THIS->nonce);
THIS->nonce = NULL;
}
if (iv_len > 13) {
THIS->nonce = string_slice(iv, 0, 12);
iv_len = 13;
} else {
add_ref(THIS->nonce = iv);
}
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | ctr_iv = STR0(THIS->ctr->iv);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
*(ctr_iv++) = 14 - iv_len;
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(ctr_iv, STR0(iv), iv_len);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(ctr_iv + iv_len, 0, 15 - iv_len);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
RETURN this_object();
}
PIKEFUN object(Nettle_AEAD_State) update(string(8bit) public_data)
{
if (!public_data->len) return;
NO_WIDE_STRING(public_data);
string_builder_shared_strcat(&THIS->abuf, public_data);
RETURN this_object();
}
static void blockcipher16_ccm_init_mac_mask(const char *caller)
{
struct pike_string *mac_mask;
if (!THIS->nonce) {
/* NB: Default to nonce of 13 NULs. */
add_ref(THIS->nonce = nul13_string);
|
babf8d | 2014-05-06 | Per Hedbor | | memcpy(THIS->ctr->iv, "\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
/* Save the first block from the CTR to encrypt the MAC. */
ref_push_string(nul16_string);
apply_current(ccm_state_inh_ctr_state_crypt_fun_num, 1);
get_all_args(caller, 1, "%n", &mac_mask);
NO_WIDE_STRING(mac_mask);
if (mac_mask->len != 16) {
Pike_error("Bad string length %ld returned from crypt()\n",
|
77af4f | 2015-10-14 | Martin Nilsson | | (long)mac_mask->len);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
if (THIS->mac_mask) free_string(THIS->mac_mask);
add_ref(THIS->mac_mask = mac_mask);
pop_stack();
}
PIKEFUN string(8bit) crypt(string(8bit) data)
{
if (!data->len) {
return;
}
NO_WIDE_STRING(data);
if (!THIS->pbuf.s->len) {
blockcipher16_ccm_init_mac_mask("crypt");
}
if (!THIS->decrypt_mode) {
string_builder_shared_strcat(&THIS->pbuf, data);
}
apply_current(ccm_state_inh_ctr_state_crypt_fun_num, args);
if (THIS->decrypt_mode) {
get_all_args("crypt", 1, "%n", &data);
NO_WIDE_STRING(data);
string_builder_shared_strcat(&THIS->pbuf, data);
}
}
/*! @decl int(4..16) digest_size()
*!
*! Default digest size.
*!
*! This function is used by @[digest()] to determine the digest
*! size if no argument was given.
*!
*! @returns
*! The default implementation returns the result from calling
*! @[global::digest_size()], but overloading via inherit is supported,
*! and may return any even number in the range @expr{[4..16]@}.
*!
*! @note
*! Note that the digest length is folded into the digest, so
*! it doesn't simply imply a truncation.
*!
*! @seealso
*! @[digest()], @[CCM::digest_size()]
*/
PIKEFUN int(4..16) digest_size()
{
apply_external(1, f_Nettle_BlockCipher16_cq__CCM_digest_size_fun_num,
args);
}
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | static void pike_low_ccm_digest(struct pike_string *res,
struct pike_string *nonce,
struct pike_string *mac_mask,
struct pike_string *astr,
struct pike_string *pstr,
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func,
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | void *ctx)
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | {
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | uint8_t buf[2][16];
size_t bytes = res->len;
size_t psize = pstr->len;
int i;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | int flags;
int bufno = 0;
uint8_t *ptr;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | flags = ((bytes-2)<<2) | (14 - nonce->len);
if (astr->len) {
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | // Set the a-bit.
flags |= 0x40;
}
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | psize = pstr->len;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
/* NB: The nonce has a minimum size of 7 bytes.
* Thus we need at most 8 bytes for the psize.
*/
/* |flags|nonce|psize| */
ptr = buf[0] + 8;
for (i = 8; i--; psize >>= 8) {
|
1c37ed | 2014-05-09 | Henrik Grubbström (Grubba) | | ptr[i] = psize & 0xff;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
buf[0][0] = flags;
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(buf[0]+1, STR0(nonce), nonce->len);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
func(ctx, 16, buf[1], buf[0]);
bufno = 1;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if (astr->len) {
size_t asize = astr->len;
ptr = STR0(astr);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | if (asize < 0xff00) {
buf[1][0] ^= (asize >> 8) & 0xff;
buf[1][1] ^= asize & 0xff;
if (asize < 14) {
memxor(buf[1]+2, ptr, asize);
asize = 0;
} else {
memxor(buf[1], ptr, 14);
ptr += 14;
asize -= 14;
}
|
59d3d4 | 2014-11-05 | Henrik Grubbström (Grubba) | | #if (SIZEOF_CHARP > 4)
} else if (asize > 0xffffffffUL) {
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | buf[1][0] ^= 0xff;
buf[1][1] ^= 0xff;
buf[1][2] ^= (asize >> 56) & 0xff;
buf[1][3] ^= (asize >> 48) & 0xff;
buf[1][4] ^= (asize >> 40) & 0xff;
buf[1][5] ^= (asize >> 32) & 0xff;
buf[1][6] ^= (asize >> 24) & 0xff;
buf[1][7] ^= (asize >> 16) & 0xff;
buf[1][8] ^= (asize >> 8) & 0xff;
buf[1][9] ^= asize & 0xff;
memxor(buf[1]+10, ptr, 6);
ptr += 6;
asize -= 6;
|
59d3d4 | 2014-11-05 | Henrik Grubbström (Grubba) | | #endif
} else {
buf[1][0] ^= 0xff;
buf[1][1] ^= 0xfe;
buf[1][2] ^= (asize >> 24) & 0xff;
buf[1][3] ^= (asize >> 16) & 0xff;
buf[1][4] ^= (asize >> 8) & 0xff;
buf[1][5] ^= asize & 0xff;
memxor(buf[1]+6, ptr, 10);
ptr += 10;
asize -= 10;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
func(ctx, 16, buf[0], buf[1]);
bufno = 0;
for (;asize >= 16; asize -= 16, ptr += 16) {
memxor(buf[bufno], ptr, 16);
func(ctx, 16, buf[!bufno], buf[bufno]);
bufno = !bufno;
}
if (asize) {
memxor(buf[bufno], ptr, asize);
func(ctx, 16, buf[!bufno], buf[bufno]);
bufno = !bufno;
}
}
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | ptr = STR0(pstr);
psize = pstr->len;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
for (; psize >= 16; psize -= 16, ptr += 16) {
memxor(buf[bufno], ptr, 16);
func(ctx, 16, buf[!bufno], buf[bufno]);
bufno = !bufno;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | if (psize) {
memxor(buf[bufno], ptr, psize);
func(ctx, 16, buf[!bufno], buf[bufno]);
bufno = !bufno;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | memxor3(STR0(res), buf[bufno], STR0(mac_mask), bytes);
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | /*! @decl string(8bit) digest(int(4..16)|void bytes)
*!
*! Returns the CBC-MAC digest of the specified size.
*!
*! @param bytes
*! Size in bytes for the desired digest. Any even number in
*! the range @expr{[4..16]@}. If not specified the value from
*! calling @[digest_size()] will be used.
*!
*! @note
*! Note that the digest length is folded into the digest, so
*! it doesn't simply imply a truncation.
*!
*! @seealso
*! @[digest_size()], @[global::digest_size()]
*/
PIKEFUN string(8bit) digest(int(4..16)|void bytes_p)
{
int bytes = 0;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | void *ctx = THIS->ctr->object;
struct pike_string *res;
struct pike_string *nonce = THIS->nonce;
struct pike_string *mac_mask = THIS->mac_mask;
struct pike_string *astr = THIS->abuf.s;
struct pike_string *pstr = THIS->pbuf.s;
if (bytes_p) {
bytes = bytes_p->u.integer;
if (bytes & 1) {
bytes++;
}
}
if (!bytes) {
apply_current(f_Nettle_BlockCipher16_cq__CCM_State_digest_size_fun_num,
0);
get_all_args("digest", 1, "%d", &bytes);
}
if (bytes < 4) {
bytes = 4;
} else if (bytes > 16) {
bytes = 16;
}
res = begin_shared_string(bytes);
if (!pstr->len) {
// Unlikely, but make sure that it is initialized.
blockcipher16_ccm_init_mac_mask("digest");
}
if (THIS->ctr->crypt_state && THIS->ctr->crypt_state->crypt) {
func = THIS->ctr->crypt_state->crypt;
ctx = THIS->ctr->crypt_state->ctx;
}
if (((THIS->abuf.s->len + THIS->pbuf.s->len) >=
CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
/* NB: This is a rather expensive MAC, as it is based
* on encrypting with CBC. */
/* Protect stuff in the object from being freed
* by a different thread while we use them.
*/
add_ref(nonce);
add_ref(mac_mask);
add_ref(astr);
add_ref(pstr);
THREADS_ALLOW();
pike_low_ccm_digest(res, nonce, mac_mask, astr, pstr, func, ctx);
THREADS_DISALLOW();
free_string(pstr);
free_string(astr);
free_string(mac_mask);
free_string(nonce);
} else {
pike_low_ccm_digest(res, nonce, mac_mask, astr, pstr, func, ctx);
}
reset_string_builder(&THIS->pbuf);
reset_string_builder(&THIS->abuf);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | |
push_string(end_shared_string(res));
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
}
/*! @endclass State
*/
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @endmodule CCM
*/
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @module CCM8
*!
*! Special case of @[CCM] where the default digest size
*! has been truncated to @expr{8@} bytes.
*!
*! @seealso
*! @[CCM], @[CBC], @[GCM], @[CTR]
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | */
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | PIKEVAR object(Nettle_AEAD) CCM8;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | PIKECLASS _CCM8
|
1d65ab | 2014-06-08 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | {
|
9de578 | 2014-08-22 | Henrik Grubbström (Grubba) | | /*! @decl inherit CCM
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | */
EXTRA
{
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | /* Perform an inherit of the _CCM class that our parent contains.
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | */
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | /* FIXME: */
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | low_inherit(Nettle_BlockCipher16_cq__CCM_program, 0,
Nettle_BlockCipher16_cq__CCM_program_fun_num,
1 + 42, 0, NULL);
|
23225e | 2014-04-30 | Henrik Grubbström (Grubba) | | }
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | /*! @decl string(8bit) name()
*! Returns the name of the base cipher with @expr{".CCM8"@} appended.
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | */
PIKEFUN string(7bit) name()
{
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | apply_external(1, f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".CCM8");
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | f_add(2);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | }
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | |
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @decl int(4..16) digest_size()
*! Default digest size.
*!
*! @returns
*! Returns @expr{8@}, but overloading via inherit is supported,
*! and may return any even number in the range @expr{[4..16]@}.
*/
PIKEFUN int(4..16) digest_size()
{
push_int(8);
}
}
/*! @endmodule CCM8
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | */
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_EAX_H
#include <nettle/eax.h>
/*! @module EAX
*!
*! Implementation of the EAX mode.
*!
*! Works as a wrapper for the cipher implemented by overloading
*! the parent class (@[BlockCipher16]).
*!
*! This is a so-called authenticated encryption with associated data
*! (AEAD) algorithm, and in addition to encryption also provides
*! message digests.
*!
*! @note
*! This mode of operation was specified as a reaction to the
*! limitiations of the @[BlockCipher16.CCM] mode.
*!
*! @note
*! Note that this module is not available in all versions of Nettle.
*!
*! @seealso
*! @[CBC], @[CTR], @[BlockCipher16.CCM], @[BlockCipher16.GCM]
*/
PIKEVAR object(Nettle_AEAD) EAX;
PIKECLASS _EAX
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit __builtin.Nettle.AEAD
*/
INHERIT "__builtin.Nettle.AEAD";
/*! @decl string(8bit) name()
*! Returns the name of the base cipher with @expr{".EAX"@} appended.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
apply_external(1, f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".EAX");
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | f_add(2);
}
/*! @decl int(1..) digest_size()
*! Default digest size.
*!
*! @returns
*! Returns @[BlockCipher::block_size()], but overloading via
*! inherit is supported, and may return any positive number
*! @expr{<= BlockCipher::block_size()@}.
*/
PIKEFUN int(1..) digest_size()
{
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
PIKEFUN int(1..) block_size()
{
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
PIKEFUN int(1..) key_size()
{
apply_external(1, f_Nettle_Cipher_key_size_fun_num, args);
}
PIKEFUN int(1..) iv_size()
{
apply_external(1, f_Nettle_Cipher_block_size_fun_num, args);
}
/*! @class State
*/
PIKECLASS State
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT|PROGRAM_CLEAR_STORAGE;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | {
PIKEVAR object object
flags ID_PRIVATE|ID_PROTECTED|ID_HIDDEN;
CVAR struct Nettle_Cipher_State_struct *crypt_state;
CVAR int block_size;
CVAR int mode;
CVAR struct eax_key eax_key;
CVAR struct eax_ctx eax_ctx;
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | /*! @decl inherit AEAD::State
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | */
EXTRA
{
/* Perform an inherit of the State class that our parent
* contains via its inherit of AEAD.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
EXIT
gc_trivial;
{
if (THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
}
/*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
*!
*! Defaults to creating the State for the cipher implemented
*! in the parent module.
*/
PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
apply_external(2, Nettle_Cipher_State_program_fun_num, 0);
}
/*! @decl void create()
*/
PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
struct inherit *inh;
int block_size;
int f;
apply_current(f_Nettle_BlockCipher16_cq__EAX_State_substate_factory_fun_num,
args);
if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
apply(o, "block_size", 0);
if(TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
block_size = Pike_sp[-1].u.integer;
if (block_size != EAX_BLOCK_SIZE)
Pike_error("Bad block size for EAX: %d.\n", block_size);
THIS->block_size = block_size;
if (THIS->object) free_object(THIS->object);
add_ref(THIS->object = o);
inh = INHERIT_FROM_INT(o->prog, f);
if (inh->prog == Nettle_Cipher_State_program) {
/* crypt() is from Nettle.Cipher.State.
*/
THIS->crypt_state = (struct Nettle_Cipher_State_struct *)
get_inherit_storage(o, inh - o->prog->inherits);
} else {
THIS->crypt_state = NULL;
}
THIS->mode = 0;
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"x.EAX"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(8bit) name()
{
apply(THIS->object, "name", args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".EAX");
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | f_add(2);
}
/*! @decl int(16..16) block_size()
*! Returns the block size of the encapsulated cipher,
*! which is always @expr{16@} for EAX.
*/
PIKEFUN int(16..16) block_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN EAX_BLOCK_SIZE;
}
/*! @decl int(1..16) digest_size()
*!
*! Default digest size.
*!
*! This function is used by @[digest()] to determine the digest
*! size if no argument was given.
*!
*! @returns
*! The default implementation returns the result from calling
*! @[EAX::digest_size()], but overloading via inherit is supported,
*! and may return any even number in the range @expr{[1..16]@}.
*!
*! @seealso
*! @[digest()], @[EAX::digest_size()]
*/
PIKEFUN int(1..16) digest_size()
optflags OPT_TRY_OPTIMIZE;
{
apply_external(1, f_Nettle_BlockCipher16_cq__EAX_digest_size_fun_num, args);
}
/*! @decl int(16..16) iv_size()
*! Returns the recommended size for the initialization vector
*! (ie @expr{16@}).
*!
*! Other sizes are allowed, but will be compressed or expanded
*! to this size using the encapsulated cipher.
*/
PIKEFUN int(16..16) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN EAX_IV_SIZE;
}
/*! @decl int(1..) key_size()
*! Returns the key size of the encapsulated cipher.
*/
PIKEFUN int(1..) key_size()
optflags OPT_EXTERNAL_DEPEND;
{
apply(THIS->object, "key_size", args);
}
/*! @decl this_program set_encrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for encrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_decrypt_key()], @[set_iv()]
*/
PIKEFUN object(Nettle_AEAD_State) set_encrypt_key(string(8bit) key,
int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
apply(THIS->object, "set_encrypt_key", args);
pop_stack();
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
eax_set_key(&THIS->eax_key, ctx, func);
THIS->mode = 0;
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for decrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_encrypt_key()], @[set_iv()]
*/
PIKEFUN object(Nettle_AEAD_State) set_decrypt_key(string(8bit) key,
int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
/* NOTE: EAX always uses the encryption function
* of the underlying cipher!
*/
apply(THIS->object, "set_encrypt_key", args);
pop_stack();
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
eax_set_key(&THIS->eax_key, ctx, func);
THIS->mode = 1;
push_object(this_object());
}
PIKEFUN object(Nettle_AEAD_State) set_iv(string(8bit) iv)
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
int iv_len = iv->len;
uint8_t *ctr_iv;
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
eax_set_nonce(&THIS->eax_ctx, &THIS->eax_key,
ctx, func, iv->len, STR0(iv));
RETURN this_object();
}
PIKEFUN object(Nettle_AEAD_State) update(string(8bit) public_data)
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
if (!public_data->len) return;
NO_WIDE_STRING(public_data);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
eax_update(&THIS->eax_ctx, &THIS->eax_key,
ctx, func, public_data->len, STR0(public_data));
RETURN this_object();
}
PIKEFUN string(8bit) crypt(string(8bit) data)
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
struct pike_string *res;
if (!data->len) {
return;
}
NO_WIDE_STRING(data);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
res = begin_shared_string(data->len);
if (!THIS->mode) {
eax_encrypt(&THIS->eax_ctx, &THIS->eax_key,
ctx, func, data->len, STR0(res), STR0(data));
} else {
eax_decrypt(&THIS->eax_ctx, &THIS->eax_key,
ctx, func, data->len, STR0(res), STR0(data));
}
push_string(end_shared_string(res));
}
/*! @decl string(8bit) digest(int(1..16)|void bytes)
*!
*! Returns the OMAC digest of the specified size.
*!
*! @param bytes
*! Size in bytes for the desired digest. Any number in the
*! range @expr{[1..16]@}. If not specified the value from
*! calling @[digest_size()] will be used.
*!
*! @seealso
*! @[digest_size()], @[global::digest_size()]
*/
PIKEFUN string(8bit) digest(int(1..16)|void bytes_p)
{
int bytes = 0;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
struct pike_string *res;
if (bytes_p) {
bytes = bytes_p->u.integer;
if (bytes & 1) {
bytes++;
}
}
if (!bytes) {
apply_current(f_Nettle_BlockCipher16_cq__EAX_State_digest_size_fun_num,
0);
get_all_args("digest", 1, "%d", &bytes);
}
if (bytes < 1) {
bytes = 1;
} else if (bytes > EAX_DIGEST_SIZE) {
bytes = EAX_DIGEST_SIZE;
}
res = begin_shared_string(bytes);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
eax_digest(&THIS->eax_ctx, &THIS->eax_key,
ctx, func, bytes, STR0(res));
push_string(end_shared_string(res));
}
}
/*! @endclass State
*/
}
/*! @endmodule EAX
*/
#endif /* HAVE_NETTLE_EAX_H */
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_GCM_H
|
7901d2 | 2014-05-07 | Tobias S. Josefowitz | |
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | #include <nettle/gcm.h>
/*! @module GCM
*! Implementation of the Galois Counter Mode (GCM).
*!
*! Works as a wrapper for the cipher implemented by overloading
|
1d65ab | 2014-06-08 | Henrik Grubbström (Grubba) | | *! the parent class (@[BlockCipher16]).
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | *!
*! This is a so-called authenticated encryption with associated data
*! (AEAD) algorithm, which in addition to encryption also provides
*! message digests.
*!
*! The operation of GCM is specified in
*! NIST Special Publication 800-38D.
*!
*! Typically accessed as @expr{Crypto.AES.GCM@} or
*! @expr{Crypto.Camellia.GCM@}
*!
*! @note
*! Note that this module is not available in all versions of Nettle.
*!
*! @seealso
*! @[CBC]
*/
PIKECLASS _GCM
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit __builtin.Nettle.AEAD
*/
INHERIT "__builtin.Nettle.AEAD";
/*! @decl string(0..255) name()
*! Returns the name of the base cipher with @expr{".GCM"@} appended.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
apply_external(1, f_Nettle_Cipher_name_fun_num, args);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".GCM");
|
9004d1 | 2014-05-11 | Henrik Grubbström (Grubba) | | f_add(2);
}
PIKEFUN int(1..) key_size()
{
apply_external(1, f_Nettle_Cipher_key_size_fun_num, args);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
/*! @decl int(16..16) block_size()
*! Returns the block size of the encapsulated cipher,
*! which is always @expr{16@} for GCM.
*/
PIKEFUN int(16..16) block_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN GCM_BLOCK_SIZE;
}
/*! @decl int(16..16) digest_size()
*! Returns the size of the generated digest,
*! which is always @expr{16@} for GCM.
*/
PIKEFUN int(16..16) digest_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN GCM_BLOCK_SIZE;
}
/*! @decl int(12..12) iv_size()
*! Returns the recommended size for the initialization vector
*! (ie @expr{12@}).
*!
*! Other sizes are allowed, but will be compressed or expanded
*! to this size using the encapsulated cipher.
*/
PIKEFUN int(12..12) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN GCM_IV_SIZE;
}
/*! @class State
*!
*! The state for a GCM instance.
*/
PIKECLASS State
|
9e336b | 2014-06-19 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT|PROGRAM_CLEAR_STORAGE;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | {
DOCSTART() @decl inherit AEAD::State
DOCEND()
EXTRA
{
/* Perform an inherit of the State class (if any) that our parent
* may contain via its inherit of __builtin.Nettle.AEAD.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
PIKEVAR object object
flags ID_PRIVATE|ID_PROTECTED|ID_HIDDEN;
CVAR struct Nettle_Cipher_State_struct *crypt_state;
CVAR INT32 mode;
CVAR INT32 dmode;
CVAR struct gcm_key gcm_key;
CVAR struct gcm_ctx gcm_ctx;
/* dmode flags */
#define NO_ADATA 1 /* Disallow associated data. */
#define NO_CDATA 2 /* Disallow crypted data. */
INIT
{
THIS->mode = -1;
}
EXIT
gc_trivial;
{
if (THIS->object) {
free_object(THIS->object);
THIS->object = NULL;
}
}
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | /*! @decl Cipher::State substate_factory()
*!
*! Returns the @[Cipher::State] object that this object
*! is to operate on.
*!
*! Defaults to creating the State for the cipher implemented
*! in the parent module.
*/
PIKEFUN object(Nettle_Cipher_State) substate_factory()
flags ID_PROTECTED;
{
apply_external(2, Nettle_Cipher_State_program_fun_num, 0);
}
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | /*! @decl void create()
*!
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | *! Initialize the GCM state with the @[Cipher::State] object
*! returned by @[substate_factory()]. This is usually
*! the State for the cipher implemented in the parent module.
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | */
PIKEFUN void create()
flags ID_PROTECTED;
{
struct object *o;
struct inherit *inh;
int f;
|
268012 | 2014-05-02 | Henrik Grubbström (Grubba) | | apply_current(f_Nettle_BlockCipher16_cq__GCM_State_substate_factory_fun_num,
0);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != T_OBJECT) {
Pike_error("Unsupported return value from Cipher::State().\n");
}
o = Pike_sp[-1].u.object;
if (!o->prog) {
Pike_error("Cipher::State() returned destructed object.\n");
}
f = find_identifier("crypt", o->prog);
if (f < 0) {
Pike_error("State object has no crypt() function.\n");
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(o, "block_size", 0);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | |
if (TYPEOF(Pike_sp[-1]) != T_INT)
Pike_error("block_size() didn't return an int.\n");
if (Pike_sp[-1].u.integer != GCM_BLOCK_SIZE)
Pike_error("cipher has an invalid block size for GCM.\n");
if (THIS->object) free_object(THIS->object);
add_ref(THIS->object = o);
inh = INHERIT_FROM_INT(o->prog, f);
if (inh->prog == Nettle_Cipher_State_program) {
/* crypt() is from Nettle.Cipher.State.
*/
THIS->crypt_state = (struct Nettle_Cipher_State_struct *)
get_inherit_storage(o, inh - o->prog->inherits);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | } else {
THIS->crypt_state = NULL;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
THIS->mode = -1;
}
/*! @decl string(0..255) name()
*! Returns the string @expr{"x.GCM"@} where x is the
*! encapsulated algorithm.
*/
PIKEFUN string(0..255) name()
optflags OPT_TRY_OPTIMIZE;
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "name", 0);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(".GCM");
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | f_add(2);
}
/*! @decl int(16..16) block_size()
*! Returns the block size of the encapsulated cipher,
*! which is always @expr{16@} for GCM.
*/
PIKEFUN int(16..16) block_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN GCM_BLOCK_SIZE;
}
/*! @decl int(16..16) digest_size()
*! Returns the size of the generated digest,
*! which is always @expr{16@} for GCM.
*/
PIKEFUN int(16..16) digest_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN GCM_BLOCK_SIZE;
}
/*! @decl int(12..12) iv_size()
*! Returns the recommended size for the initialization vector
*! (ie @expr{12@}).
*!
*! Other sizes are allowed, but will be compressed or expanded
*! to this size using the encapsulated cipher.
*/
PIKEFUN int(12..12) iv_size()
optflags OPT_TRY_OPTIMIZE;
{
RETURN GCM_IV_SIZE;
}
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | /*! @decl int(1..) key_size()
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | *! Returns the key size of the encapsulated cipher.
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | PIKEFUN int(1..) key_size()
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | optflags OPT_EXTERNAL_DEPEND;
{
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "key_size", args);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
/*! @decl this_program set_encrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for encrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_decrypt_key()], @[set_iv()]
*/
PIKEFUN object set_encrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_encrypt_key", args);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | pop_stack();
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
gcm_set_key(&THIS->gcm_key, ctx, func);
THIS->mode = 0;
push_object(this_object());
}
/*! @decl this_program set_decrypt_key(string(0..255) key, int|void flags)
*!
*! Prepare the cipher and the wrapper for decrypting with the given
*! @[key]. The @[key] memory will be cleared before released.
*!
*! @note
*! Note that this operation does not by itself reset the
*! context sufficiently to start a new message; @[set_iv()]
*! needs to be called too.
*!
*! @seealso
*! @[set_encrypt_key()], @[set_iv()]
*/
PIKEFUN object set_decrypt_key(string(0..255) key, int|void flags)
optflags OPT_SIDE_EFFECT;
{
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
key->flags |= STRING_CLEAR_ON_EXIT;
/* NOTE: GCM always uses the encryption function
* of the underlying cipher!
*/
|
8c5373 | 2014-05-13 | Henrik Grubbström (Grubba) | | apply(THIS->object, "set_encrypt_key", args);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | pop_stack();
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
gcm_set_key(&THIS->gcm_key, ctx, func);
THIS->mode = 1;
push_object(this_object());
}
/*! @decl this_program set_iv(string(0..255) iv)
*!
*! Set the initialization vector to @[iv]. The @[iv] memory will be
*! cleared before released.
*!
*! Also resets all state needed to start a new message.
*!
*! @note
*! For @[iv]s of length other than @expr{12@}, an encryption or
*! decryption key must have been set first.
*!
*! @seealso
*! @[set_encrypt_key()], @[set_decrypt_key()].
*/
PIKEFUN object set_iv(string(0..255) iv)
optflags OPT_SIDE_EFFECT;
{
iv->flags |= STRING_CLEAR_ON_EXIT;
NO_WIDE_STRING(iv);
if ((THIS->mode < 0) && (iv->len != GCM_IV_SIZE))
Pike_error("The key must be set to use an iv of length other than %d.\n",
GCM_IV_SIZE);
gcm_set_iv(&THIS->gcm_ctx, &THIS->gcm_key, iv->len, STR0(iv));
THIS->dmode = 0;
RETURN this_object();
}
/*! @decl void update(string(0..255) public_data)
*!
*! Add @[public_data] to be authenticated.
*!
*! The length of @[public_data] MUST be a multiple of the
*! block size (ie @expr{16@}) for all calls except the last.
*!
*! All calls of @[update()] need to be performed before
*! any calls of @[crypt()].
*/
PIKEFUN void update(string(0..255) data)
{
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | struct gcm_ctx *gcm_ctx = &THIS->gcm_ctx;
struct gcm_key *gcm_key = &THIS->gcm_key;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | NO_WIDE_STRING(data);
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
if (THIS->mode < 0)
Pike_error("Key schedule not initialized.\n");
if (THIS->dmode & NO_ADATA)
Pike_error("Public data not allowed now.\n");
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if (data->len >= HASH_THREADS_ALLOW_THRESHOLD) {
THREADS_ALLOW();
gcm_update(gcm_ctx, gcm_key, data->len, STR0(data));
THREADS_DISALLOW();
} else {
gcm_update(gcm_ctx, gcm_key, data->len, STR0(data));
}
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | |
if (data->len & (GCM_BLOCK_SIZE - 1))
THIS->dmode |= NO_ADATA;
}
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypt/decrypt @[data] and return the result. @[data] must
*! be an integral number of blocks.
*!
*! The length of @[data] MUST be a multiple of the block size
*! (ie @expr{16@}) for all calls except the last.
*!
*! Neither the input or output data is not automatically memory
*! scrubbed, unless @[String.secure] has been called on the data.
*!
*! @seealso
*! @[update()], @[digest()]
*/
PIKEFUN string(0..255) crypt(string(0..255) data)
{
struct pike_string *result;
ONERROR uwp;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | struct gcm_ctx *gcm_ctx = &THIS->gcm_ctx;
struct gcm_key *gcm_key = &THIS->gcm_key;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | |
NO_WIDE_STRING(data);
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
if (THIS->mode < 0)
Pike_error("Key schedule not initialized.\n");
if (THIS->dmode & NO_CDATA)
Pike_error("More data not allowed before the iv is reset.\n");
result = begin_shared_string(data->len);
SET_ONERROR (uwp, do_free_string, result);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
if (!THIS->mode) {
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
THREADS_ALLOW();
gcm_encrypt(gcm_ctx, gcm_key, ctx, func,
data->len, STR0(result), STR0(data));
THREADS_DISALLOW();
} else {
gcm_encrypt(gcm_ctx, gcm_key, ctx, func,
data->len, STR0(result), STR0(data));
}
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | } else {
|
0473d5 | 2014-05-11 | Henrik Grubbström (Grubba) | | if ((data->len >= CIPHER_THREADS_ALLOW_THRESHOLD) &&
(func != pike_crypt_func)) {
THREADS_ALLOW();
gcm_decrypt(gcm_ctx, gcm_key, ctx, func,
data->len, STR0(result), STR0(data));
THREADS_DISALLOW();
} else {
gcm_decrypt(gcm_ctx, gcm_key, ctx, func,
data->len, STR0(result), STR0(data));
}
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
THIS->dmode |= NO_ADATA;
if (data->len & (GCM_BLOCK_SIZE - 1))
THIS->dmode |= NO_CDATA;
pop_n_elems(args);
push_string(end_shared_string(result));
UNSET_ONERROR(uwp);
}
/*! @decl string(0..255) digest()
*!
*! Generate a message digest for the data accumulated so far.
*!
*! @note
*! @[set_iv()] needs to be called to start the next message.
*!
*! @seealso
*! @[update()], @[digest()]
*/
PIKEFUN string(0..255) digest()
{
struct pike_string *result;
ONERROR uwp;
|
fd073e | 2014-06-23 | Henrik Grubbström (Grubba) | | pike_nettle_crypt_func func = pike_crypt_func;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | void *ctx = THIS->object;
if (!THIS->object || !THIS->object->prog) {
Pike_error("Lookup in destructed object.\n");
}
if (THIS->mode < 0)
Pike_error("Key schedule not initialized.\n");
result = begin_shared_string(GCM_BLOCK_SIZE);
SET_ONERROR (uwp, do_free_string, result);
if (THIS->crypt_state && THIS->crypt_state->crypt) {
func = THIS->crypt_state->crypt;
ctx = THIS->crypt_state->ctx;
}
gcm_digest(&THIS->gcm_ctx, &THIS->gcm_key, ctx, func,
GCM_BLOCK_SIZE, STR0(result));
THIS->dmode |= NO_ADATA | NO_CDATA;
pop_n_elems(args);
push_string(end_shared_string(result));
UNSET_ONERROR(uwp);
}
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @endclass State
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | */
}
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | /*! @endmodule GCM
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | */
#endif /* HAVE_NETTLE_GCM_H */
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | /* NB: Declare the storage explicitly to avoid having it declared
* inside the #ifdef above.
*/
DECLARE_STORAGE;
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | INIT
{
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | apply_current(Nettle_BlockCipher16_cq__CCM_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER16->CCM = Pike_sp[-1].u.object);
}
pop_stack();
apply_current(Nettle_BlockCipher16_cq__CCM8_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER16->CCM8 = Pike_sp[-1].u.object);
}
pop_stack();
|
9ce28d | 2014-06-09 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_EAX_H
apply_current(Nettle_BlockCipher16_cq__EAX_program_fun_num, 0);
if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
add_ref(THIS_NETTLE_BLOCKCIPHER16->EAX = Pike_sp[-1].u.object);
}
pop_stack();
#endif
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_GCM_H
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | apply_current(Nettle_BlockCipher16_cq__GCM_program_fun_num, 0);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | add_ref(THIS_NETTLE_BLOCKCIPHER16->GCM = Pike_sp[-1].u.object);
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | }
pop_stack();
#endif
}
}
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @endclass BlockCipher16
|
ef8460 | 2014-04-26 | Henrik Grubbström (Grubba) | | */
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #define BLOCKCIPHER16_CIPHER_INHERIT (BLOCKCIPHER_CIPHER_INHERIT + 1)
|
662c98 | 2003-11-09 | Niels Möller | | static void
pike_aes_set_encrypt_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
c735c0 | 2003-03-18 | Niels Möller | | {
|
662c98 | 2003-11-09 | Niels Möller | | if (length == 16 || length == 24 || length == 32)
|
20e2ef | 2005-12-12 | Martin Nilsson | | aes_set_encrypt_key(ctx, length, (const uint8_t *)key);
|
662c98 | 2003-11-09 | Niels Möller | | else
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("AES: Bad keysize for AES.\n");
|
662c98 | 2003-11-09 | Niels Möller | | }
static void
pike_aes_set_decrypt_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
662c98 | 2003-11-09 | Niels Möller | | {
if (length == 16 || length == 24 || length == 32)
|
20e2ef | 2005-12-12 | Martin Nilsson | | aes_set_decrypt_key(ctx, length, (const uint8_t *)key);
|
662c98 | 2003-11-09 | Niels Möller | | else
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("AES: Bad keysize for AES.\n");
|
c735c0 | 2003-03-18 | Niels Möller | | }
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK16_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME AES
#cmod_define NETTLE_NAME aes
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_include "cipher.H"
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
c735c0 | 2003-03-18 | Niels Möller | |
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | static void pike_arctwo_set_key(void *ctx,
ptrdiff_t length, const char *key,
int ekb)
{
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | if (!ekb) ekb = 128;
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | if (length < ARCTWO_MIN_KEY_SIZE || length > ARCTWO_MAX_KEY_SIZE)
Pike_error("ARCTWO: Bad keysize for ARCTWO.\n");
arctwo_set_key_ekb(ctx, length, (const uint8_t *)key, ekb);
}
#define pike_arctwo_set_encrypt_key pike_arctwo_set_key
#define pike_arctwo_set_decrypt_key pike_arctwo_set_key
/*! @class ARCTWO
*!
*! Implementation of the ARCTWO cipher.
*!
*/
PIKECLASS ARCTWO
{
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BlockCipher
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | */
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BlockCipher;
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | |
|
6a6354 | 2013-10-31 | Henrik Grubbström (Grubba) | | static const struct pike_cipher pike_arctwo =
_PIKE_CIPHER(arctwo, ARCTWO);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *cipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | ASSIGN_CURRENT_STORAGE(cipher, struct Nettle_Cipher_struct,
BLOCKCIPHER_CIPHER_INHERIT + 1,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | Nettle_Cipher_program);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | cipher->meta = &pike_arctwo;
}
/*! @class State
*!
*! State for PIKE_NAME encyption.
*!
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit Cipher::State
*/
|
6a6354 | 2013-10-31 | Henrik Grubbström (Grubba) | | static int f_ARCTWO_State_inherited_set_encrypt_key_fun_num = -1;
static int f_ARCTWO_State_inherited_set_decrypt_key_fun_num = -1;
|
8f28a2 | 2013-10-28 | Henrik Grubbström (Grubba) | |
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | EXTRA
{
/* Perform an inherit of the Cipher.State class that our parent
* contains via its inherit of Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
|
6a6354 | 2013-10-31 | Henrik Grubbström (Grubba) | | f_ARCTWO_State_inherited_set_encrypt_key_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | f_Nettle_Cipher_State_set_encrypt_key_fun_num);
|
6a6354 | 2013-10-31 | Henrik Grubbström (Grubba) | | f_ARCTWO_State_inherited_set_decrypt_key_fun_num =
really_low_reference_inherited_identifier(NULL, 1,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | f_Nettle_Cipher_State_set_decrypt_key_fun_num);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | }
}
}
CVAR struct arctwo_ctx arctwo;
INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | state->ctx = &THIS->arctwo;
}
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl State set_encrypt_key(string(0..255) key, int|void ekb)
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | *!
*! Initializes the object for encryption. The @[key] memory will be
*! cleared before released.
*!
*! @param ekb
*! The effective number of bits in the key.
*! @int
*! @value UNDEFINED
*! Derive from the key size (ie @expr{8 * sizeof(key)@}).
*! @value 0
*! Convenience alias for max (ie @expr{1024@}).
*! @value 1..1024
*! Reduce the effective key size to the specified number of bits.
*! @endint
*!
*! @seealso
*! @[set_decrypt_key], @[crypt]
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN object set_encrypt_key(string(0..255) key, void|int(0..1024) ekb)
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | optflags OPT_SIDE_EFFECT;
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | rawtype tFunc(tStr8 tOr(tInt, tVoid), tObjImpl_NETTLE_CIPHER_STATE);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | {
NO_WIDE_STRING(key);
if (!ekb) {
if (args > 1) pop_n_elems(args - 1);
push_int(key->len * 8);
args = 2;
}
|
6a6354 | 2013-10-31 | Henrik Grubbström (Grubba) | | apply_current(f_ARCTWO_State_inherited_set_encrypt_key_fun_num, args);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | }
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl State set_decrypt_key(string(0..255) key, void|int ekb)
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | *!
*! Initializes the object for decryption. The @[key] memory will be
*! cleared before released.
*!
*! @param ekb
*! The effective number of bits in the key.
*! @int
*! @value UNDEFINED
*! Derive from the key size (ie @expr{8 * sizeof(key)@}).
*! @value 0
*! Convenience alias for max (ie @expr{1024@}).
*! @value 1..1024
*! Reduce the effective key size to the specified number of bits.
*! @endint
*!
*! @seealso
*! @[set_encrypt_key], @[crypt]
*/
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | PIKEFUN object set_decrypt_key(string(0..255) key, void|int ekb)
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | optflags OPT_SIDE_EFFECT;
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | rawtype tFunc(tStr8 tOr(tInt, tVoid), tObjImpl_NETTLE_CIPHER_STATE);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | {
NO_WIDE_STRING(key);
if (!ekb) {
if (args > 1) pop_n_elems(args - 1);
push_int(key->len * 8);
args = 2;
}
|
6a6354 | 2013-10-31 | Henrik Grubbström (Grubba) | | apply_current(f_ARCTWO_State_inherited_set_decrypt_key_fun_num, args);
|
07e4b6 | 2013-10-28 | Henrik Grubbström (Grubba) | | }
}
/*! @endclass State
*/
}
/*! @endclass ARCTWO
*/
|
662c98 | 2003-11-09 | Niels Möller | | static void
pike_arcfour_set_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
8417e5 | 2003-08-24 | Martin Nilsson | | {
|
662c98 | 2003-11-09 | Niels Möller | | if (length < ARCFOUR_MIN_KEY_SIZE || length > ARCFOUR_MAX_KEY_SIZE)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("ARCFOUR: Bad keysize for ARCFOUR.\n");
|
662c98 | 2003-11-09 | Niels Möller | |
|
20e2ef | 2005-12-12 | Martin Nilsson | | arcfour_set_key(ctx, length, (const uint8_t *)key);
|
8417e5 | 2003-08-24 | Martin Nilsson | | }
|
f8b724 | 2015-04-17 | Martin Nilsson | |
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_arcfour_set_encrypt_key pike_arcfour_set_key
#define pike_arcfour_set_decrypt_key pike_arcfour_set_key
#define arcfour_encrypt arcfour_crypt
#define arcfour_decrypt arcfour_crypt
|
5040d8 | 2003-11-29 | Martin Nilsson | | #define ARCFOUR_BLOCK_SIZE 1
|
8417e5 | 2003-08-24 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE STREAM_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME ARCFOUR
#cmod_define NETTLE_NAME arcfour
#cmod_include "cipher.H"
#cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
8417e5 | 2003-08-24 | Martin Nilsson | |
|
85fc8e | 2011-04-21 | Martin Nilsson | | #ifdef HAVE_NETTLE_BLOWFISH_DECRYPT
|
dc4a97 | 2008-07-17 | Martin Stjernholm | |
|
662c98 | 2003-11-09 | Niels Möller | | static void
pike_blowfish_set_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
c1f5ab | 2003-08-26 | Martin Nilsson | | {
|
662c98 | 2003-11-09 | Niels Möller | | if (length < BLOWFISH_MIN_KEY_SIZE || length > BLOWFISH_MAX_KEY_SIZE)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("BLOWFISH: Bad keysize for BLOWFISH.\n");
|
20e2ef | 2005-12-12 | Martin Nilsson | | if (!blowfish_set_key(ctx, length, (const uint8_t *)key))
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("BLOWFISH: Key is weak (and force flag is currently ignored).\n");
|
c1f5ab | 2003-08-26 | Martin Nilsson | | }
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_blowfish_set_encrypt_key pike_blowfish_set_key
#define pike_blowfish_set_decrypt_key pike_blowfish_set_key
|
c1f5ab | 2003-08-26 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME BLOWFISH
#cmod_define NETTLE_NAME blowfish
#cmod_include "cipher.H"
#cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
1b3471 | 2003-08-25 | Martin Nilsson | |
|
85fc8e | 2011-04-21 | Martin Nilsson | | #endif /* HAVE_NETTLE_BLOWFISH_DECRYPT */
|
dc4a97 | 2008-07-17 | Martin Stjernholm | |
|
5ea703 | 2014-04-21 | Henrik Grubbström (Grubba) | | #if !defined(CAMELLIA_KEY_SIZE) && defined(CAMELLIA128_KEY_SIZE)
/* Nettle 3.0.
*
* Emulate the previous API where the Camellia variants were joined.
*/
#define CAMELLIA_KEY_SIZE CAMELLIA256_KEY_SIZE
struct camellia_ctx
{
union {
struct camellia128_ctx ctx128;
struct camellia192_ctx ctx192;
struct camellia256_ctx ctx256;
} u;
unsigned keylen;
};
|
45382e | 2014-04-23 | Martin Nilsson | | static void camellia_set_encrypt_key(void *ctx, unsigned len,
const uint8_t *key)
|
5ea703 | 2014-04-21 | Henrik Grubbström (Grubba) | | {
struct camellia_ctx *camellia_ctx = ctx;
switch(len) {
case CAMELLIA128_KEY_SIZE:
camellia128_set_encrypt_key(&camellia_ctx->u.ctx128, key);
break;
case CAMELLIA192_KEY_SIZE:
camellia192_set_encrypt_key(&camellia_ctx->u.ctx192, key);
break;
case CAMELLIA256_KEY_SIZE:
camellia256_set_encrypt_key(&camellia_ctx->u.ctx256, key);
break;
default:
Pike_fatal("Invalid keylength for Camellia: %d\n", len);
break;
}
camellia_ctx->keylen = len;
}
|
45382e | 2014-04-23 | Martin Nilsson | | static void camellia_set_decrypt_key(void *ctx, unsigned len,
const uint8_t *key)
|
5ea703 | 2014-04-21 | Henrik Grubbström (Grubba) | | {
struct camellia_ctx *camellia_ctx = ctx;
switch(len) {
case CAMELLIA128_KEY_SIZE:
camellia128_set_decrypt_key(&camellia_ctx->u.ctx128, key);
break;
case CAMELLIA192_KEY_SIZE:
camellia192_set_decrypt_key(&camellia_ctx->u.ctx192, key);
break;
case CAMELLIA256_KEY_SIZE:
camellia256_set_decrypt_key(&camellia_ctx->u.ctx256, key);
break;
default:
Pike_fatal("Invalid keylength for Camellia: %d\n", len);
break;
}
camellia_ctx->keylen = len;
}
static void camellia_crypt(struct camellia_ctx *ctx, unsigned length,
uint8_t *dst, const uint8_t *src)
{
switch(ctx->keylen) {
case CAMELLIA128_KEY_SIZE:
camellia128_crypt(&ctx->u.ctx128, length, dst, src);
break;
case CAMELLIA192_KEY_SIZE:
camellia192_crypt(&ctx->u.ctx192, length, dst, src);
break;
case 0:
case CAMELLIA256_KEY_SIZE:
camellia256_crypt(&ctx->u.ctx256, length, dst, src);
break;
default:
Pike_fatal("Invalid keylength for Camellia: %d\n", ctx->keylen);
break;
}
}
#endif
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | #ifdef CAMELLIA_KEY_SIZE
|
5ea703 | 2014-04-21 | Henrik Grubbström (Grubba) | | #ifndef CAMELLIA128_KEY_SIZE
#define CAMELLIA128_KEY_SIZE 16
#endif
#ifndef CAMELLIA192_KEY_SIZE
#define CAMELLIA192_KEY_SIZE 24
#endif
#ifndef CAMELLIA256_KEY_SIZE
#define CAMELLIA256_KEY_SIZE 32
#endif
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | static void
pike_camellia_set_encrypt_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | {
|
5ea703 | 2014-04-21 | Henrik Grubbström (Grubba) | | if (length != CAMELLIA128_KEY_SIZE &&
length != CAMELLIA256_KEY_SIZE &&
length != CAMELLIA192_KEY_SIZE)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("CAMELLIA: Bad keysize for CAMELLIA.\n");
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | camellia_set_encrypt_key(ctx, length, (const uint8_t *)key);
}
static void
pike_camellia_set_decrypt_key(void *ctx,
ptrdiff_t length, const char *key,
|
61017f | 2014-02-25 | Per Hedbor | | int UNUSED(force))
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | {
|
5ea703 | 2014-04-21 | Henrik Grubbström (Grubba) | | if (length != CAMELLIA128_KEY_SIZE &&
length != CAMELLIA256_KEY_SIZE &&
length != CAMELLIA192_KEY_SIZE)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("CAMELLIA: Bad keysize for CAMELLIA.\n");
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | camellia_set_decrypt_key(ctx, length, (const uint8_t *)key);
}
#define camellia_encrypt camellia_crypt
#define camellia_decrypt camellia_crypt
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK16_MODE
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME CAMELLIA
#cmod_define NETTLE_NAME camellia
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_include "cipher.H"
|
650f10 | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
#endif /* CAMELLIA_KEY_SIZE */
|
662c98 | 2003-11-09 | Niels Möller | | static void
pike_cast128_set_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
408f68 | 2003-07-29 | Martin Nilsson | | {
|
9e7520 | 2014-03-18 | Martin Nilsson | | #ifdef CAST5_MIN_KEY_SIZE
if (length < CAST5_MIN_KEY_SIZE || length > CAST5_MAX_KEY_SIZE)
Pike_error("CAST128_info: Bad keysize for CAST128.\n");
cast5_set_key(ctx, length, (const uint8_t *)key);
#else
|
662c98 | 2003-11-09 | Niels Möller | | if (length < CAST128_MIN_KEY_SIZE || length > CAST128_MAX_KEY_SIZE)
Pike_error("CAST128_info: Bad keysize for CAST128.\n");
|
20e2ef | 2005-12-12 | Martin Nilsson | |
cast128_set_key(ctx, length, (const uint8_t *)key);
|
9e7520 | 2014-03-18 | Martin Nilsson | | #endif
|
408f68 | 2003-07-29 | Martin Nilsson | | }
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_cast128_set_encrypt_key pike_cast128_set_key
#define pike_cast128_set_decrypt_key pike_cast128_set_key
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME CAST128
#cmod_define NETTLE_NAME cast128
#cmod_include "cipher.H"
#cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | #ifdef HAVE_NETTLE_CHACHA_H
static void
pike_chacha_set_key(void *ctx,
ptrdiff_t length, const char *key,
int UNUSED(force))
{
if (length != CHACHA_KEY_SIZE)
Pike_error("CHACHA: Bad keysize for CHACHA.\n");
chacha_set_key(ctx, (const uint8_t *)key);
}
#define pike_chacha_set_encrypt_key pike_chacha_set_key
#define pike_chacha_set_decrypt_key pike_chacha_set_key
#define chacha_encrypt chacha_crypt
#define chacha_decrypt chacha_crypt
/*! @class CHACHA
*!
*! Implementation of the CHACHA stream cipher.
*!
*! @note
*! Note that this class is not available in all versions of Nettle.
*!
*/
PIKECLASS CHACHA
{
|
f30d99 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BlockCipher
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | */
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BlockCipher;
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | |
static const struct pike_cipher pike_chacha =
_PIKE_CIPHER(chacha, CHACHA);
INIT
{
struct Nettle_Cipher_struct *cipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | ASSIGN_CURRENT_STORAGE(cipher, struct Nettle_Cipher_struct,
BLOCKCIPHER_CIPHER_INHERIT + 1,
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | Nettle_Cipher_program);
cipher->meta = &pike_chacha;
}
/*! @class State
*!
*! State for CHACHA encyption.
*!
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
/*! @decl inherit Cipher::State
*/
EXTRA
{
/* Perform an inherit of the Cipher.State class that our parent
* contains via its inherit of Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
CVAR struct chacha_ctx chacha;
/*! @decl string(0..255) crypt(string(0..255) data)
*!
*! Encrypts or decrypts data, using the current key. Neither the
*! input nor output data is automatically memory scrubbed,
*! unless @[String.secure] has been called on them.
*!
*! @param data
*! Usually an integral number of blocks, except for the last
*! segement in a run. The decoder must get partial blocks
*! at the same places as the encoder, otherwise they will get
*! out of sync.
*!
*! @returns
*! The encrypted or decrypted data.
*/
PIKEFUN string(0..255) crypt (string(0..255) data)
optflags OPT_EXTERNAL_DEPEND | OPT_SIDE_EFFECT;
{
struct pike_string *s;
NO_WIDE_STRING(data);
/* NB: Differs from default in that the block size
* isn't enforced.
*
* To simplify the code we also skip the indirection
* via the Cipher class and its State.
*/
s = begin_shared_string(data->len);
chacha_crypt(&THIS->chacha, data->len, (uint8_t *)s->str,
(const uint8_t *)data->str);
s = end_shared_string(s);
push_string(s);
}
/*! @decl object set_iv(string(0..255) iv)
*!
*! Set the initialization vector (aka nonce) and reset
*! the block counter to zero.
*!
*! @param iv
*! An 8-byte long string which is only to be used
*! once for every key.
*!
*! @note
*! This function MUST be called in addition to
*! @[set_encrypt_key()] or @[set_decrypt_key()].
*!
*! @note
*! The same @[iv] should NEVER be reused with the same key!
*/
PIKEFUN object set_iv(string(0..255) iv)
rawtype tFunc(tStr8, tObjImpl_NETTLE_CIPHER_STATE);
{
NO_WIDE_STRING(iv);
if (iv->len != CHACHA_NONCE_SIZE)
Pike_error("CHACHA IV needs to be %d bytes.\n", CHACHA_NONCE_SIZE);
iv->flags |= STRING_CLEAR_ON_EXIT;
|
be52b8 | 2014-05-13 | Martin Nilsson | | chacha_set_nonce(&THIS->chacha, STR0(iv));
|
24b0bd | 2014-04-18 | Henrik Grubbström (Grubba) | | push_object(this_object());
}
INIT
{
struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
state->ctx = &THIS->chacha;
}
}
/*! @endclass State
*/
}
/*! @endclass CHACHA
*/
#endif /* HAVE_NETTLE_CHACHA_H */
|
3b588a | 2003-10-05 | Martin Nilsson | | static void
|
662c98 | 2003-11-09 | Niels Möller | | pike_des_set_key(void *c,
ptrdiff_t length, const char *key,
int force)
|
3b588a | 2003-10-05 | Martin Nilsson | | {
|
662c98 | 2003-11-09 | Niels Möller | | struct des_ctx *ctx = (struct des_ctx *) c;
if (length != 8)
Pike_error("DES_INFO: Bad keysize for DES.\n");
|
20e2ef | 2005-12-12 | Martin Nilsson | | if (!des_set_key(ctx, (const uint8_t *)key))
|
662c98 | 2003-11-09 | Niels Möller | | {
|
60000c | 2011-04-17 | Henrik Grubbström (Grubba) | | #ifndef DES_WEAK_KEY
/* Nettle 2.1 and later. */
if (!force)
Pike_error("DES_INFO: Key is weak.\n");
#else
/* Nettle 2.0 and earlier. */
|
662c98 | 2003-11-09 | Niels Möller | | switch (ctx->status)
{
case DES_WEAK_KEY:
if (force)
/* Use key anyway */
ctx->status = DES_OK;
else
Pike_error("DES_INFO: Key is weak.\n");
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
662c98 | 2003-11-09 | Niels Möller | | case DES_BAD_PARITY:
Pike_error("DES_INFO: Key has bad parity.\n");
default:
Pike_error("DES_INFO: Unexpected error, please send a bug report.\n");
}
|
60000c | 2011-04-17 | Henrik Grubbström (Grubba) | | #endif
|
662c98 | 2003-11-09 | Niels Möller | | }
|
3b588a | 2003-10-05 | Martin Nilsson | | }
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_des_set_encrypt_key pike_des_set_key
#define pike_des_set_decrypt_key pike_des_set_key
|
3b588a | 2003-10-05 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @class DES
|
3b588a | 2003-10-05 | Martin Nilsson | | *!
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *! Implementation of the Data Encryption Standard (DES) crypto algorithm.
*!
*/
PIKECLASS DES
|
3b588a | 2003-10-05 | Martin Nilsson | | {
|
f30d99 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BlockCipher
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | */
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BlockCipher;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
|
3b588a | 2003-10-05 | Martin Nilsson | | INIT
{
|
662c98 | 2003-11-09 | Niels Möller | | static const struct pike_cipher pike_des = _PIKE_CIPHER(des, DES);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* FIXME: Ought to traverse the inherit graph for
* the current program.
*/
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *cipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | ASSIGN_CURRENT_STORAGE(cipher, struct Nettle_Cipher_struct,
BLOCKCIPHER_CIPHER_INHERIT + 1,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | Nettle_Cipher_program);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | cipher->meta = &pike_des;
|
3b588a | 2003-10-05 | Martin Nilsson | | }
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) fix_parity(string(0..255) key)
|
fc0689 | 2003-11-27 | Martin Nilsson | | *! Sets the last bit in every byte in @[key] to reflect the parity.
*! If a seven byte key is used, it will be expanded into eight
*! bytes. If a key longer than eight characters is used, it will
*! be truncated to eight characters.
*/
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) fix_parity(string(0..255) key)
|
3b588a | 2003-10-05 | Martin Nilsson | | {
uint8_t buf[8];
|
5345c9 | 2013-05-19 | Martin Nilsson | |
NO_WIDE_STRING(key);
|
3b588a | 2003-10-05 | Martin Nilsson | | if(key->len < 7)
Pike_error("Key must be at least 7 characters.\n");
if(key->len == 7) {
buf[0] = key->str[0]&254;
buf[1] = (key->str[0]&1)<<7 | (key->str[1]>>1 & 126);
buf[2] = (key->str[1]&3)<<6 | (key->str[2]>>2 & 62);
buf[3] = (key->str[2]&7)<<5 | (key->str[3]>>3 & 30);
buf[4] = (key->str[3]&15)<<4 | (key->str[4]>>4 & 14);
buf[5] = (key->str[4]&31)<<3 | (key->str[5]>>5 & 6);
buf[6] = (key->str[5]&63)<<2 | (key->str[6]>>6 & 2);
buf[7] = (key->str[6]&127)<<1;
}
else
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(buf, key->str, 8);
|
3b588a | 2003-10-05 | Martin Nilsson | |
|
662c98 | 2003-11-09 | Niels Möller | | des_fix_parity(8, buf, buf);
|
20e2ef | 2005-12-12 | Martin Nilsson | | RETURN make_shared_binary_string((char *)buf, 8);
|
3b588a | 2003-10-05 | Martin Nilsson | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @class State
*!
*! State for DES encyption
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
DOCSTART() @decl inherit Cipher::State
DOCEND()
|
3b588a | 2003-10-05 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | EXTRA
|
3b588a | 2003-10-05 | Martin Nilsson | | {
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* Perform an inherit of the Cipher.State class that our parent
* contains via its inherit of Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
|
3b588a | 2003-10-05 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | CVAR struct des_ctx des;
INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
|
3b588a | 2003-10-05 | Martin Nilsson | | state->ctx = &THIS->des;
}
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) make_key()
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | assert(info);
|
95b365 | 2013-11-29 | Martin Nilsson | | #ifndef DES_WEAK_KEY
|
f3ac58 | 2014-10-21 | Henrik Grubbström (Grubba) | | /* NB: This loop temporarily leaks strings on the stack,
* but we don't care, as it is a low probability,
* and they will be cleaned up on return.
*/
|
95b365 | 2013-11-29 | Martin Nilsson | | do {
low_make_key(info->meta->key_size);
|
b7580b | 2014-10-20 | Henrik Grubbström (Grubba) | | f_Nettle_DES_fix_parity(1);
|
95b365 | 2013-11-29 | Martin Nilsson | | } while( !des_set_key(state->ctx,
(const uint8_t *)Pike_sp[-1].u.string->str) );
#else
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | low_make_key(info->meta->key_size);
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | f_Nettle_DES_fix_parity(1);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
info->meta->set_encrypt_key(state->ctx, Pike_sp[-1].u.string->len,
Pike_sp[-1].u.string->str, 0);
|
95b365 | 2013-11-29 | Martin Nilsson | | #endif
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
|
95b365 | 2013-11-29 | Martin Nilsson | | Pike_sp[-1].u.string->flags |= STRING_CLEAR_ON_EXIT;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | state->crypt = info->meta->encrypt;
state->key_size = Pike_sp[-1].u.string->len;
}
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) fix_parity(string(0..255) key)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *! Sets the last bit in every byte in @[key] to reflect the parity.
*! If a seven byte key is used, it will be expanded into eight
*! bytes. If a key longer than eight characters is used, it will
*! be truncated to eight characters.
*/
PIKEFUN string(0..255) fix_parity(string(0..255) key)
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | apply_external(1, f_Nettle_DES_fix_parity_fun_num, args);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | }
|
e39ad6 | 2013-10-22 | Henrik Grubbström (Grubba) | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @endclass State */
|
3b588a | 2003-10-05 | Martin Nilsson | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @endclass DES */
|
3b588a | 2003-10-05 | Martin Nilsson | |
|
a980cf | 2014-09-10 | Henrik Grubbström (Grubba) | | DEFAULT_CMOD_STORAGE void f_Nettle_DES3_fix_parity(INT32);
|
804806 | 2003-12-06 | Martin Nilsson | |
|
ab38b3 | 2003-10-08 | Martin Nilsson | | static void
|
662c98 | 2003-11-09 | Niels Möller | | pike_des3_set_key(void *c,
|
b0fb07 | 2004-10-08 | Martin Nilsson | | ptrdiff_t length, const char *key,
|
662c98 | 2003-11-09 | Niels Möller | | int force)
|
ab38b3 | 2003-10-08 | Martin Nilsson | | {
|
662c98 | 2003-11-09 | Niels Möller | | struct des3_ctx *ctx = (struct des3_ctx *) c;
int i;
|
274f7d | 2004-01-23 | Martin Nilsson | | char nkotb[24];
|
5e68dc | 2003-11-29 | Martin Nilsson | |
switch( length ) {
case 7+7:
push_string(make_shared_binary_string(key, length));
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text("1234567");
|
5e68dc | 2003-11-29 | Martin Nilsson | | f_add(2);
|
1c213a | 2014-03-29 | Martin Nilsson | | f_Nettle_DES3_fix_parity(1);
|
5e68dc | 2003-11-29 | Martin Nilsson | |
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(nkotb, Pike_sp[-1].u.string->str, 8+8);
|
5e68dc | 2003-11-29 | Martin Nilsson | | pop_stack();
key = nkotb;
length = 8+8;
/* fallthrough */
case 8+8:
push_string(make_shared_binary_string(key, length));
push_string(make_shared_binary_string(key, length));
push_int(0);
push_int(7);
o_range();
f_add(2);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(nkotb, Pike_sp[-1].u.string->str, 8+8+8);
|
5e68dc | 2003-11-29 | Martin Nilsson | | pop_stack();
key = nkotb;
length = 8+8+8;
break;
case 7+7+7:
push_string(make_shared_binary_string(key, length));
|
1c213a | 2014-03-29 | Martin Nilsson | | f_Nettle_DES3_fix_parity(1);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(nkotb, Pike_sp[-1].u.string->str, 8+8+8);
|
5e68dc | 2003-11-29 | Martin Nilsson | | pop_stack();
key = nkotb;
length = 8+8+8;
break;
case 8+8+8:
break;
default:
|
662c98 | 2003-11-09 | Niels Möller | | Pike_error("DES3_INFO: Bad keysize for DES3.\n");
|
5e68dc | 2003-11-29 | Martin Nilsson | | break;
}
|
662c98 | 2003-11-09 | Niels Möller | |
|
95b365 | 2013-11-29 | Martin Nilsson | | #ifndef DES_WEAK_KEY
if( !des3_set_key(ctx, (const uint8_t *)key) && !force )
Pike_error("DES3_INFO: Key is weak.\n");
#else
|
662c98 | 2003-11-09 | Niels Möller | | /* The hack of resetting ctx->status to use a weak key doesn't
* currently work with nettle's des3_set_key function. So we set the
* individual keys by ourself. */
for (i = 0; i<3; i++, key += DES_KEY_SIZE)
|
20e2ef | 2005-12-12 | Martin Nilsson | | if (!des_set_key(&ctx->des[i], (const uint8_t *)key))
|
60000c | 2011-04-17 | Henrik Grubbström (Grubba) | | {
/* Nettle 2.0 and earlier. */
|
662c98 | 2003-11-09 | Niels Möller | | switch (ctx->des[i].status)
{
case DES_WEAK_KEY:
if (force)
/* Use key anyway */
ctx->des[i].status = DES_OK;
else
Pike_error("DES3_INFO: Key is weak.\n");
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
662c98 | 2003-11-09 | Niels Möller | | case DES_BAD_PARITY:
Pike_error("DES3_INFO: Key has bad parity.\n");
default:
Pike_error("DES3_INFO: Unexpected error, please send a bug report.\n");
|
60000c | 2011-04-17 | Henrik Grubbström (Grubba) | | }
|
662c98 | 2003-11-09 | Niels Möller | | }
|
95b365 | 2013-11-29 | Martin Nilsson | | #endif
|
ab38b3 | 2003-10-08 | Martin Nilsson | | }
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_des3_set_encrypt_key pike_des3_set_key
#define pike_des3_set_decrypt_key pike_des3_set_key
|
ab38b3 | 2003-10-08 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @class DES3
|
ab38b3 | 2003-10-08 | Martin Nilsson | | *!
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | *! Implementation of the DES3 cipher algorithm.
*!
*/
PIKECLASS DES3
|
ab38b3 | 2003-10-08 | Martin Nilsson | | {
|
f30d99 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BlockCipher
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | */
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BlockCipher;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
|
ab38b3 | 2003-10-08 | Martin Nilsson | | INIT
{
|
662c98 | 2003-11-09 | Niels Möller | | static const struct pike_cipher pike_des3 = _PIKE_CIPHER(des3, DES3);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* FIXME: Ought to traverse the inherit graph for
* the current program.
*/
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *cipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | ASSIGN_CURRENT_STORAGE(cipher, struct Nettle_Cipher_struct,
BLOCKCIPHER_CIPHER_INHERIT + 1,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | Nettle_Cipher_program);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | cipher->meta = &pike_des3;
|
ab38b3 | 2003-10-08 | Martin Nilsson | | }
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
f6a6ad | 2013-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string(0..255) fix_parity(string(0..255) key)
|
d55fde | 2003-11-28 | Martin Nilsson | | *! Sets the last bit in every byte in @[key] to reflect the parity.
*! If a 21 byte key is used, it will be expanded into 24
*! bytes. If a key longer than 24 characters is used, it will
*! be truncated to 24 characters.
*/
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) fix_parity(string(0..255) key)
|
d55fde | 2003-11-28 | Martin Nilsson | | {
|
675b55 | 2003-11-29 | Martin Nilsson | | INT32 i;
|
d55fde | 2003-11-28 | Martin Nilsson | | struct array *arr;
|
5345c9 | 2013-05-19 | Martin Nilsson | | NO_WIDE_STRING(key);
|
d55fde | 2003-11-28 | Martin Nilsson | | if(key->len < 24 && key->len != 21)
Pike_error("Key must be 21 or >=24 characters.\n");
/* Split the string */
if(key->len==21)
push_int(7);
else
push_int(8);
f_divide(2);
arr = Pike_sp[-1].u.array;
add_ref(arr);
pop_stack();
/* fix_parity for every subkey */
for(i=0; i<3; i++) {
|
675b55 | 2003-11-29 | Martin Nilsson | | push_int(0);
array_index(&Pike_sp[-1], arr, i);
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | f_Nettle_DES_fix_parity(1);
|
d55fde | 2003-11-28 | Martin Nilsson | | }
|
675b55 | 2003-11-29 | Martin Nilsson | | free_array(arr);
|
d55fde | 2003-11-28 | Martin Nilsson | |
/* Join the subkeys */
f_add(3);
}
|
ab38b3 | 2003-10-08 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @class State
*!
*! State for DES3 encyption
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
DOCSTART() @decl inherit Cipher::State
DOCEND()
|
ab38b3 | 2003-10-08 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | EXTRA
|
ab38b3 | 2003-10-08 | Martin Nilsson | | {
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /* Perform an inherit of the Cipher.State class that our parent
* contains via its inherit of Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | 1 + 42, 0, NULL);
}
}
}
|
ab38b3 | 2003-10-08 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | CVAR struct des3_ctx des3;
INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
|
ab38b3 | 2003-10-08 | Martin Nilsson | | state->ctx = &THIS->des3;
}
|
d55fde | 2003-11-28 | Martin Nilsson | |
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..255) make_key()
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *info = GET_INFO();
struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | assert(info);
|
95b365 | 2013-11-29 | Martin Nilsson | | #ifndef DES_WEAK_KEY
|
f3ac58 | 2014-10-21 | Henrik Grubbström (Grubba) | | /* NB: This loop temporarily leaks strings on the stack,
* but we don't care, as it is a low probability,
* and they will be cleaned up on return.
*/
|
95b365 | 2013-11-29 | Martin Nilsson | | do {
low_make_key(info->meta->key_size);
|
b7580b | 2014-10-20 | Henrik Grubbström (Grubba) | | f_Nettle_DES3_fix_parity(1);
|
95b365 | 2013-11-29 | Martin Nilsson | | } while( !des3_set_key(state->ctx,
(const uint8_t *)Pike_sp[-1].u.string->str) );
#else
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | low_make_key(info->meta->key_size);
|
1c213a | 2014-03-29 | Martin Nilsson | | f_Nettle_DES3_fix_parity(1);
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
info->meta->set_encrypt_key(state->ctx, Pike_sp[-1].u.string->len,
Pike_sp[-1].u.string->str, 0);
|
95b365 | 2013-11-29 | Martin Nilsson | | #endif
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
|
95b365 | 2013-11-29 | Martin Nilsson | | Pike_sp[-1].u.string->flags |= STRING_CLEAR_ON_EXIT;
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | state->crypt = info->meta->encrypt;
state->key_size = Pike_sp[-1].u.string->len;
}
|
d55fde | 2003-11-28 | Martin Nilsson | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | /*! @endclass State */
|
ab38b3 | 2003-10-08 | Martin Nilsson | | }
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | |
/*! @endclass DES3 */
|
ab38b3 | 2003-10-08 | Martin Nilsson | |
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | #ifdef HAVE_NETTLE_SALSA20_CRYPT
static void
pike_salsa20_set_key(void *ctx,
ptrdiff_t length, const char *key,
int UNUSED(force))
{
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | if ((length != SALSA20_MIN_KEY_SIZE) && (length != SALSA20_MAX_KEY_SIZE))
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | Pike_error("SALSA20: Bad keysize for SALSA20.\n");
salsa20_set_key(ctx, length, (const uint8_t *)key);
}
#define pike_salsa20_set_encrypt_key pike_salsa20_set_key
#define pike_salsa20_set_decrypt_key pike_salsa20_set_key
#define salsa20_encrypt salsa20_crypt
#define salsa20_decrypt salsa20_crypt
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | /*! @class SALSA20
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | *!
*! Implementation of the SALSA20 cipher.
*!
*/
PIKECLASS SALSA20
{
|
f30d99 | 2014-04-30 | Henrik Grubbström (Grubba) | | /*! @decl inherit BlockCipher
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | */
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | INHERIT Nettle_BlockCipher;
|
f3b8d4 | 2013-11-12 | Martin Nilsson | |
static const struct pike_cipher pike_salsa20 =
_PIKE_CIPHER(salsa20, SALSA20);
INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *cipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | ASSIGN_CURRENT_STORAGE(cipher, struct Nettle_Cipher_struct,
BLOCKCIPHER_CIPHER_INHERIT + 1,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | Nettle_Cipher_program);
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | cipher->meta = &pike_salsa20;
}
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | /*! @class State
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | *!
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | *! State for SALSA20 encyption.
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | *!
*/
PIKECLASS State
program_flags PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT;
{
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | /*! @decl inherit Cipher::State
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | */
EXTRA
{
/* Perform an inherit of the Cipher.State class that our parent
* contains via its inherit of Cipher.
*/
struct program *parent_prog = Pike_compiler->previous->new_program;
struct object *parent_obj = Pike_compiler->previous->fake_object;
int parent_State_fun_num =
really_low_find_shared_string_identifier(MK_STRING("State"),
parent_prog,
SEE_PROTECTED|SEE_PRIVATE);
if (parent_State_fun_num >= 0) {
struct program *parent_State_prog =
low_program_from_function(parent_obj, parent_State_fun_num);
if (parent_State_prog) {
|
27b78a | 2014-10-06 | Henrik Grubbström (Grubba) | | parent_State_fun_num =
really_low_reference_inherited_identifier(Pike_compiler->previous,
0, parent_State_fun_num);
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | low_inherit(parent_State_prog, 0,
|
bc7cd5 | 2014-06-21 | Henrik Grubbström (Grubba) | | parent_State_fun_num,
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | 1 + 42, 0, NULL);
}
}
}
CVAR struct salsa20_ctx salsa20;
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | /*! @decl object set_iv(string(0..255) iv)
*!
*! Set the initialization vector (aka nonce) and reset
*! the block counter to zero.
*!
*! @param iv
*! An 8-byte long string which is only to be used
*! once for every key.
*!
*! @note
*! This function MUST be called in addition to
*! @[set_encrypt_key()] or @[set_decrypt_key()].
*!
*! @note
*! The same @[iv] should NEVER be reused with the same key!
*/
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | PIKEFUN object set_iv(string(0..255) iv)
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | rawtype tFunc(tStr8, tObjImpl_NETTLE_CIPHER_STATE);
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | {
NO_WIDE_STRING(iv);
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | if (iv->len != SALSA20_IV_SIZE)
Pike_error("SALSA20 IV needs to be %d bytes.\n", SALSA20_IV_SIZE);
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | iv->flags |= STRING_CLEAR_ON_EXIT;
|
1a3110 | 2014-05-13 | Henrik Grubbström (Grubba) | | salsa20_set_iv(&THIS->salsa20, STR0(iv));
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | push_object(this_object());
}
INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_State_struct *state;
ASSIGN_CURRENT_STORAGE(state, struct Nettle_Cipher_State_struct, 1,
Nettle_Cipher_State_program);
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | state->ctx = &THIS->salsa20;
}
}
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | /*! @endclass State
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | */
}
|
2beea7 | 2013-11-12 | Henrik Grubbström (Grubba) | | /*! @endclass SALSA20
|
f3b8d4 | 2013-11-12 | Martin Nilsson | | */
|
7baa0a | 2013-11-18 | Martin Nilsson | | #ifdef salsa20r12_crypt
|
536931 | 2013-11-15 | Henrik Grubbström (Grubba) | | #define pike_salsa20r12_set_encrypt_key pike_salsa20_set_encrypt_key
#define pike_salsa20r12_set_decrypt_key pike_salsa20_set_decrypt_key
#define salsa20r12_encrypt salsa20r12_crypt
#define salsa20r12_decrypt salsa20r12_crypt
#define salsa20r12_ctx salsa20_ctx
#define SALSA20R12_BLOCK_SIZE SALSA20_BLOCK_SIZE
#define SALSA20R12_KEY_SIZE SALSA20_KEY_SIZE
/*! @class SALSA20R12
*!
*! Implementation of the @[SALSA20] cipher reduced to 12 rounds.
*!
*/
PIKECLASS SALSA20R12
{
/*! @decl inherit SALSA20
*/
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | INHERIT Nettle_SALSA20;
|
536931 | 2013-11-15 | Henrik Grubbström (Grubba) | |
static const struct pike_cipher pike_salsa20r12 =
_PIKE_CIPHER(salsa20r12, SALSA20R12);
INIT
{
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | struct Nettle_Cipher_struct *cipher;
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | /* NB: We know that BlockCipher is the first inherit of SALSA20. */
ASSIGN_CURRENT_STORAGE(cipher, struct Nettle_Cipher_struct,
BLOCKCIPHER_CIPHER_INHERIT + 2,
|
895c72 | 2014-03-29 | Henrik Grubbström (Grubba) | | Nettle_Cipher_program);
|
536931 | 2013-11-15 | Henrik Grubbström (Grubba) | | cipher->meta = &pike_salsa20r12;
}
}
/*! @endclass SALSA20R12
*/
|
7baa0a | 2013-11-18 | Martin Nilsson | | #endif /* salsa20r12_crypt */
|
536931 | 2013-11-15 | Henrik Grubbström (Grubba) | | #endif /* HAVE_NETTLE_SALSA20_CRYPT */
|
f3b8d4 | 2013-11-12 | Martin Nilsson | |
|
85fc8e | 2011-04-21 | Martin Nilsson | | #ifdef HAVE_NETTLE_SERPENT_DECRYPT
|
dc4a97 | 2008-07-17 | Martin Stjernholm | |
|
662c98 | 2003-11-09 | Niels Möller | | static void
pike_serpent_set_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
408f68 | 2003-07-29 | Martin Nilsson | | {
|
662c98 | 2003-11-09 | Niels Möller | | if (length < SERPENT_MIN_KEY_SIZE || length > SERPENT_MAX_KEY_SIZE)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("SERPENT: Bad keysize for SERPENT.\n");
|
13670c | 2015-05-25 | Martin Nilsson | |
|
20e2ef | 2005-12-12 | Martin Nilsson | | serpent_set_key(ctx, length, (const uint8_t *)key);
|
408f68 | 2003-07-29 | Martin Nilsson | | }
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_serpent_set_encrypt_key pike_serpent_set_key
#define pike_serpent_set_decrypt_key pike_serpent_set_key
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK16_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME SERPENT
#cmod_define NETTLE_NAME serpent
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_include "cipher.H"
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
85fc8e | 2011-04-21 | Martin Nilsson | | #endif /* HAVE_NETTLE_SERPENT_DECRYPT */
|
dc4a97 | 2008-07-17 | Martin Stjernholm | |
|
662c98 | 2003-11-09 | Niels Möller | | static void
pike_twofish_set_key(void *ctx,
ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
408f68 | 2003-07-29 | Martin Nilsson | | {
|
662c98 | 2003-11-09 | Niels Möller | | if (length < TWOFISH_MIN_KEY_SIZE || length > TWOFISH_MAX_KEY_SIZE)
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("TWOFISH: Bad keysize for TWOFISH.\n");
|
662c98 | 2003-11-09 | Niels Möller | |
|
20e2ef | 2005-12-12 | Martin Nilsson | | twofish_set_key(ctx, length, (const uint8_t *)key);
|
408f68 | 2003-07-29 | Martin Nilsson | | }
|
662c98 | 2003-11-09 | Niels Möller | | #define pike_twofish_set_encrypt_key pike_twofish_set_key
#define pike_twofish_set_decrypt_key pike_twofish_set_key
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #define Twofish_BLOCK_SIZE TWOFISH_BLOCK_SIZE
#define Twofish_KEY_SIZE TWOFISH_KEY_SIZE
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK16_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME Twofish
#cmod_define NETTLE_NAME twofish
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_include "cipher.H"
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
408f68 | 2003-07-29 | Martin Nilsson | |
|
82b27a | 2004-09-16 | Martin Nilsson | | #ifdef WITH_IDEA
|
fc0689 | 2003-11-27 | Martin Nilsson | | static void
|
766bc8 | 2004-10-16 | Marcus Agehall | | pike_idea_set_encrypt_key(void *ctx_v,
|
fc0689 | 2003-11-27 | Martin Nilsson | | ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
fc0689 | 2003-11-27 | Martin Nilsson | | {
|
766bc8 | 2004-10-16 | Marcus Agehall | | struct idea_ctx *ctx = ctx_v;
|
fc0689 | 2003-11-27 | Martin Nilsson | | if (length == IDEA_KEY_SIZE)
|
5e68dc | 2003-11-29 | Martin Nilsson | | idea_expand((unsigned INT16 *)ctx->ctx, (unsigned INT8 *)key);
|
fc0689 | 2003-11-27 | Martin Nilsson | | else
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("IDEA: Bad keysize for IDEA.\n");
|
fc0689 | 2003-11-27 | Martin Nilsson | | }
static void
|
766bc8 | 2004-10-16 | Marcus Agehall | | pike_idea_set_decrypt_key(void *ctx_v,
|
fc0689 | 2003-11-27 | Martin Nilsson | | ptrdiff_t length, const char *key,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | int UNUSED(force))
|
fc0689 | 2003-11-27 | Martin Nilsson | | {
|
766bc8 | 2004-10-16 | Marcus Agehall | | struct idea_ctx *ctx = ctx_v;
|
fc0689 | 2003-11-27 | Martin Nilsson | | if (length == IDEA_KEY_SIZE) {
|
5e68dc | 2003-11-29 | Martin Nilsson | | idea_expand((unsigned INT16 *)ctx->ctx, (unsigned INT8 *)key);
idea_invert((unsigned INT16 *)ctx->ctx, (unsigned INT16 *)ctx->ctx);
|
fc0689 | 2003-11-27 | Martin Nilsson | | }
else
|
4d6595 | 2013-10-21 | Henrik Grubbström (Grubba) | | Pike_error("IDEA: Bad keysize for IDEA.\n");
|
fc0689 | 2003-11-27 | Martin Nilsson | | }
#define idea_encrypt idea_crypt_blocks
#define idea_decrypt idea_crypt_blocks
|
374728 | 2014-04-30 | Henrik Grubbström (Grubba) | | #cmod_define CIPHER_MODE BLOCK_MODE
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #cmod_define PIKE_NAME IDEA
#cmod_define NETTLE_NAME idea
#cmod_include "cipher.H"
#cmod_undef PIKE_NAME
#cmod_undef NETTLE_NAME
|
fc0689 | 2003-11-27 | Martin Nilsson | |
|
5667be | 2011-12-23 | Henrik Grubbström (Grubba) | | #endif /* WITH_IDEA */
|
fc0689 | 2003-11-27 | Martin Nilsson | |
|
c735c0 | 2003-03-18 | Niels Möller | | /*! @endmodule Nettle */
void
cipher_init(void)
{
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | nul13_string = begin_shared_string(13);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(STR0(nul13_string), 0, 13);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | nul13_string = end_shared_string(nul13_string);
nul16_string = begin_shared_string(16);
|
21b12a | 2014-09-03 | Martin Nilsson | | memset(STR0(nul16_string), 0, 16);
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | nul16_string = end_shared_string(nul16_string);
|
1c37ed | 2014-05-09 | Henrik Grubbström (Grubba) | |
|
c735c0 | 2003-03-18 | Niels Möller | | INIT;
|
3773e2 | 2014-03-19 | Martin Nilsson | | ADD_INT_CONSTANT("PAD_SSL", PAD_SSL, 0);
ADD_INT_CONSTANT("PAD_ISO_10126", PAD_ISO_10126, 0);
ADD_INT_CONSTANT("PAD_ANSI_X923", PAD_ANSI_X923, 0);
ADD_INT_CONSTANT("PAD_PKCS7", PAD_PKCS7, 0);
ADD_INT_CONSTANT("PAD_ZERO", PAD_ZERO, 0);
|
82ba33 | 2014-03-26 | Martin Nilsson | | ADD_INT_CONSTANT("PAD_TLS", PAD_TLS, 0);
|
c735c0 | 2003-03-18 | Niels Möller | | }
void
cipher_exit(void)
{
EXIT;
|
9b6951 | 2014-05-01 | Henrik Grubbström (Grubba) | | free_string(nul16_string);
free_string(nul13_string);
|
c735c0 | 2003-03-18 | Niels Möller | | }
#endif /* HAVE_LIBNETTLE */
|