AES128

 view release on metacpan or  search on metacpan

AES128.xs  view on Meta::CPAN

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include "aes.h"
#include "aes.c"


void make_aes_key(char *key, char *secret, size_t secret_size)
{
	uint8_t i, m, n;
	// make a 32 bytes key from secret.
	if(secret_size >= 32) {
		memcpy(key, secret, 32);
	}
	else {
		m = 32 % secret_size;
		n = (32 - m) / secret_size;
		for(i = 0; i < n; i++) {
			memcpy(key + secret_size * i, secret, secret_size);
		}
		memcpy(key + secret_size * i, secret, m);
	}
}

MODULE = AES128		PACKAGE = AES128		

TYPEMAP: <<END
const char *    T_PV
const uint8_t *    T_PV
uint8_t * T_PV
END

SV *
AES128_CTR_encrypt(SV *sv_plain_text, SV *sv_secret)
	CODE:
		STRLEN text_size, secret_size;
		uint8_t i;
		struct AES_ctx ctx;
		char *plain_text, *secret, *output;

		plain_text = (char *)SvPVbyte(sv_plain_text, text_size);
		secret     = (char *)SvPVbyte(sv_secret, secret_size);
		char key[32];
		make_aes_key(key, secret, secret_size);

		uint8_t padding_len = 16 - text_size % 16;

		output = (char *)malloc(text_size + padding_len);
		memcpy(output, plain_text, text_size);
		for(i = 0; i < padding_len; i++) 
			output[text_size + i] = padding_len;

		AES_init_ctx_iv(&ctx, key, key + 16);
		AES_CTR_xcrypt_buffer(&ctx, output, text_size + padding_len);
		RETVAL = newSVpv(output, text_size + padding_len);
		free(output);
	OUTPUT:
		RETVAL

SV *
AES128_CTR_decrypt(SV *sv_cipher_text, SV *sv_secret)
	CODE:
		STRLEN text_size, secret_size;
		char *cipher_text, *secret;
		struct AES_ctx ctx;
		char key[32];

		cipher_text = (char *)SvPVbyte(sv_cipher_text, text_size);
		secret = (char *)SvPVbyte(sv_secret, secret_size);
		if(text_size % 16 != 0)
			croak("Corrupted cipher text!");

		make_aes_key(key, secret, secret_size);

		AES_init_ctx_iv(&ctx, key, key + 16);
		AES_CTR_xcrypt_buffer(&ctx, cipher_text, text_size);
		uint8_t padding_len = cipher_text[text_size -1];
		RETVAL = newSVpv(cipher_text, text_size - padding_len);
	OUTPUT:
		RETVAL

lib/AES128.pm  view on Meta::CPAN


=head1 NAME

AES128 - 128BIT CTR mode AES algorithm. 

=head1 SYNOPSIS

	# ------------------------  simple version ----------------------------------
	use AES128 qw/:all/;
	my $plain_text = "There's more than one way to do it.";
	my $key = "my secret aes key.";
	my $encrypted = AES128_CTR_encrypt($plain_text, $key);
	my $plain     = AES128_CTR_decrypt($encrypted, $key);


	# ------------ server/client key exchange -----------------------------------
	use MicroECC;
	use AES128 qw/:all/;
	use Digest::SHA qw/sha256/;

	my $curve = MicroECC::secp256r1();
	my ($server_pubkey, $server_privkey) = MicroECC::make_key($curve);

	# Generate shared secret with client public key.
	my $shared_secret = MicroECC::shared_secret($client_pubkey, $server_privkey);
	my $key = sha256($shared_secret);

	my $plain_text = "There's more than one way to do it.";
	my $encrypted  = AES128_CTR_encrypt($plain_text, $key);
	my $plain      = AES128_CTR_decrypt($encrypted, $key);

=head1 DESCRIPTION

Perl wrapper for the tiny-AES-c library (https://github.com/kokke/tiny-AES-c)

Since 128bit key length is secure enough for most applications and ECB is NOT secure,
this module supports 128bit key length and CTR mode only.

=head2 EXPORT

None by default.


=head1 SEE ALSO

The tiny-AES-c library: https://github.com/kokke/tiny-AES-c

ppport.h  view on Meta::CPAN

macro. Just C<#define> the macro before including C<ppport.h>:

    #define DPPP_NAMESPACE MyOwnNamespace_
    #include "ppport.h"

The default namespace is C<DPPP_>.

=back

The good thing is that most of the above can be checked by running
F<ppport.h> on your source code. See the next section for
details.

=head1 EXAMPLES

To verify whether F<ppport.h> is needed for your module, whether you
should make any changes to your code, and whether any special defines
should be used, F<ppport.h> can be run as a Perl script to check your
source code. Simply say:

    perl ppport.h

ppport.h  view on Meta::CPAN

_add_range_to_invlist|||
_append_range_to_invlist|||
_core_swash_init|||
_get_encoding|||
_get_regclass_nonbitmap_data|||
_get_swash_invlist|||
_invlistEQ|||
_invlist_array_init|||n
_invlist_contains_cp|||n
_invlist_dump|||
_invlist_intersection_maybe_complement_2nd|||
_invlist_intersection|||
_invlist_invert|||
_invlist_len|||n
_invlist_populate_swatch|||n
_invlist_search|||n
_invlist_subtract|||
_invlist_union_maybe_complement_2nd|||
_invlist_union|||
_is_cur_LC_category_utf8|||
_is_in_locale_category||5.021001|
_is_uni_FOO||5.017008|

ppport.h  view on Meta::CPAN

sortsv||5.007003|
space_join_names_mortal|||
ss_dup|||
ssc_add_range|||
ssc_and|||
ssc_anything|||
ssc_clear_locale|||n
ssc_cp_and|||
ssc_finalize|||
ssc_init|||
ssc_intersection|||
ssc_is_anything|||n
ssc_is_cp_posixl_init|||n
ssc_or|||
ssc_union|||
stack_grow|||
start_glob|||
start_subparse||5.004000|
stdize_locale|||
strEQ|||
strGE|||

ppport.h  view on Meta::CPAN

 * data from C.  All statics in extensions should be reworked to use
 * this, if you want to make the extension thread-safe.  See ext/re/re.xs
 * for an example of the use of these macros.
 *
 * Code that uses these macros is responsible for the following:
 * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts"
 * 2. Declare a typedef named my_cxt_t that is a structure that contains
 *    all the data that needs to be interpreter-local.
 * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
 * 4. Use the MY_CXT_INIT macro such that it is called exactly once
 *    (typically put in the BOOT: section).
 * 5. Use the members of the my_cxt_t structure everywhere as
 *    MY_CXT.member.
 * 6. Use the dMY_CXT macro (a declaration) in all the functions that
 *    access MY_CXT.
 */

#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \
    defined(PERL_CAPI)    || defined(PERL_IMPLICIT_CONTEXT)

#ifndef START_MY_CXT

tiny-AES-c/aes.c  view on Meta::CPAN

{
  uint8_t temp;

  // Rotate first row 1 columns to left  
  temp           = (*state)[0][1];
  (*state)[0][1] = (*state)[1][1];
  (*state)[1][1] = (*state)[2][1];
  (*state)[2][1] = (*state)[3][1];
  (*state)[3][1] = temp;

  // Rotate second row 2 columns to left  
  temp           = (*state)[0][2];
  (*state)[0][2] = (*state)[2][2];
  (*state)[2][2] = temp;

  temp           = (*state)[1][2];
  (*state)[1][2] = (*state)[3][2];
  (*state)[3][2] = temp;

  // Rotate third row 3 columns to left
  temp           = (*state)[0][3];

tiny-AES-c/aes.c  view on Meta::CPAN

{
  uint8_t temp;

  // Rotate first row 1 columns to right  
  temp = (*state)[3][1];
  (*state)[3][1] = (*state)[2][1];
  (*state)[2][1] = (*state)[1][1];
  (*state)[1][1] = (*state)[0][1];
  (*state)[0][1] = temp;

  // Rotate second row 2 columns to right 
  temp = (*state)[0][2];
  (*state)[0][2] = (*state)[2][2];
  (*state)[2][2] = temp;

  temp = (*state)[1][2];
  (*state)[1][2] = (*state)[3][2];
  (*state)[3][2] = temp;

  // Rotate third row 3 columns to right
  temp = (*state)[0][3];

tiny-AES-c/aes.h  view on Meta::CPAN


void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif

#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes; 
// you need only AES_init_ctx as IV is not used in ECB 
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf);

#endif // #if defined(ECB) && (ECB == !)


#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()



( run in 1.055 second using v1.01-cache-2.11-cpan-39bf76dae61 )