Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nettle/nettle
  • briansmith/nettle
  • ajlawrence/nettle
  • mhoffmann/nettle
  • devnexen/nettle
  • wiml/nettle
  • lumag/nettle
  • michaelweiser/nettle
  • aberaud/nettle
  • mamonet/nettle
  • npocs/nettle
  • babelouest/nettle
  • ueno/nettle
  • rth/nettle
14 results
Show changes
/* aes192-encrypt.c
Encryption function for the aes/rijndael block cipher.
Copyright (C) 2002, 2013 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
/* For fat builds */
#if HAVE_NATIVE_aes192_encrypt
void
_nettle_aes192_encrypt_c(const struct aes192_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src);
# define nettle_aes192_encrypt _nettle_aes192_encrypt_c
#endif
void
nettle_aes192_encrypt(const struct aes192_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
assert(!(length % AES_BLOCK_SIZE) );
_nettle_aes_encrypt(_AES192_ROUNDS, ctx->keys, &_nettle_aes_encrypt_table,
length, dst, src);
}
/* aes192-meta.c
Copyright (C) 2013, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "nettle-meta.h"
#include "aes.h"
const struct nettle_cipher nettle_aes192 =
{ "aes192", sizeof(struct aes192_ctx),
AES_BLOCK_SIZE, AES192_KEY_SIZE,
(nettle_set_key_func *) aes192_set_encrypt_key,
(nettle_set_key_func *) aes192_set_decrypt_key,
(nettle_cipher_func *) aes192_encrypt,
(nettle_cipher_func *) aes192_decrypt
};
/* aes192-set-decrypt-key.c
Copyright (C) 2013, Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
#include "macros.h"
/* For fat builds */
#if HAVE_NATIVE_aes192_invert_key
void
_nettle_aes192_invert_key_c(struct aes192_ctx *dst,
const struct aes192_ctx *src);
# define nettle_aes192_invert_key _nettle_aes192_invert_key_c
#endif
#if HAVE_NATIVE_aes192_set_decrypt_key
void
_nettle_aes192_set_decrypt_key_c(struct aes192_ctx *ctx, const uint8_t *key);
# define nettle_aes192_set_decrypt_key _nettle_aes192_set_decrypt_key_c
#endif
void
nettle_aes192_invert_key (struct aes192_ctx *dst, const struct aes192_ctx *src)
{
_nettle_aes_invert (_AES192_ROUNDS, dst->keys, src->keys);
}
void
nettle_aes192_set_decrypt_key(struct aes192_ctx *ctx, const uint8_t *key)
{
aes192_set_encrypt_key (ctx, key);
aes192_invert_key (ctx, ctx);
}
/* aes192-set-encrypt-key.c
Copyright (C) 2013, Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
/* For fat builds */
#if HAVE_NATIVE_aes192_set_encrypt_key
void
_nettle_aes192_set_encrypt_key_c(struct aes192_ctx *ctx, const uint8_t *key);
# define nettle_aes192_set_encrypt_key _nettle_aes192_set_encrypt_key_c
#endif
void
nettle_aes192_set_encrypt_key(struct aes192_ctx *ctx, const uint8_t *key)
{
_nettle_aes_set_key (_AES192_ROUNDS, AES192_KEY_SIZE / 4, ctx->keys, key);
}
/* aes256-decrypt.c
Decryption function for aes/rijndael block cipher.
Copyright (C) 2002, 2013 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
/* For fat builds */
#if HAVE_NATIVE_aes256_decrypt
void
_nettle_aes256_decrypt_c(const struct aes256_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src);
# define nettle_aes256_decrypt _nettle_aes256_decrypt_c
#endif
void
nettle_aes256_decrypt(const struct aes256_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
assert(!(length % AES_BLOCK_SIZE) );
_nettle_aes_decrypt(_AES256_ROUNDS, ctx->keys + 4 * _AES256_ROUNDS,
&_nettle_aes_decrypt_table, length, dst, src);
}
/* aes256-encrypt.c
Encryption function for the aes/rijndael block cipher.
Copyright (C) 2002, 2013 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
/* For fat builds */
#if HAVE_NATIVE_aes256_encrypt
void
_nettle_aes256_encrypt_c(const struct aes256_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src);
# define nettle_aes256_encrypt _nettle_aes256_encrypt_c
#endif
void
nettle_aes256_encrypt(const struct aes256_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
assert(!(length % AES_BLOCK_SIZE) );
_nettle_aes_encrypt(_AES256_ROUNDS, ctx->keys, &_nettle_aes_encrypt_table,
length, dst, src);
}
/* aes256-meta.c
Copyright (C) 2013, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "nettle-meta.h"
#include "aes.h"
const struct nettle_cipher nettle_aes256 =
{ "aes256", sizeof(struct aes256_ctx),
AES_BLOCK_SIZE, AES256_KEY_SIZE,
(nettle_set_key_func *) aes256_set_encrypt_key,
(nettle_set_key_func *) aes256_set_decrypt_key,
(nettle_cipher_func *) aes256_encrypt,
(nettle_cipher_func *) aes256_decrypt
};
/* aes256-set-decrypt-key.c
Copyright (C) 2013, Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
#include "macros.h"
/* For fat builds */
#if HAVE_NATIVE_aes256_invert_key
void
_nettle_aes256_invert_key_c(struct aes256_ctx *dst,
const struct aes256_ctx *src);
# define nettle_aes256_invert_key _nettle_aes256_invert_key_c
#endif
#if HAVE_NATIVE_aes256_set_decrypt_key
void
_nettle_aes256_set_decrypt_key_c(struct aes256_ctx *ctx, const uint8_t *key);
# define nettle_aes256_set_decrypt_key _nettle_aes256_set_decrypt_key_c
#endif
void
nettle_aes256_invert_key (struct aes256_ctx *dst, const struct aes256_ctx *src)
{
_nettle_aes_invert (_AES256_ROUNDS, dst->keys, src->keys);
}
void
nettle_aes256_set_decrypt_key(struct aes256_ctx *ctx, const uint8_t *key)
{
aes256_set_encrypt_key (ctx, key);
aes256_invert_key (ctx, ctx);
}
/* aes256-set-encrypt-key.c
Copyright (C) 2013, Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes-internal.h"
/* For fat builds */
#if HAVE_NATIVE_aes256_set_encrypt_key
void
_nettle_aes256_set_encrypt_key_c(struct aes256_ctx *ctx, const uint8_t *key);
# define nettle_aes256_set_encrypt_key _nettle_aes256_set_encrypt_key_c
#endif
void
nettle_aes256_set_encrypt_key(struct aes256_ctx *ctx, const uint8_t *key)
{
_nettle_aes_set_key (_AES256_ROUNDS, AES256_KEY_SIZE / 4, ctx->keys, key);
}
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "nettle-types.h"
#if 1
# define BYTE_FORMAT "0x%02x"
# define BYTE_COLUMNS 8
......@@ -17,17 +11,18 @@
# define BYTE_COLUMNS 0x10
#endif
#define WORD_FORMAT "0x%08x"
#define WORD_FORMAT "0x%08lx"
#define WORD_COLUMNS 4
uint8_t sbox[0x100];
uint8_t isbox[0x100];
unsigned char sbox[0x100];
unsigned char isbox[0x100];
uint8_t log[0x100];
uint8_t ilog[0x100];
unsigned char gf2_log[0x100];
unsigned char gf2_exp[0x100];
uint32_t dtable[4][0x100];
uint32_t itable[4][0x100];
unsigned long dtable[4][0x100];
unsigned long itable[4][0x100];
unsigned long mtable[4][0x100];
static unsigned
xtime(unsigned x)
......@@ -51,30 +46,30 @@ compute_log(void)
unsigned i = 0;
unsigned x = 1;
memset(log, 0, 0x100);
memset(gf2_log, 0, 0x100);
for (i = 0; i < 0x100; i++, x = x ^ xtime(x))
{
ilog[i] = x;
log[x] = i;
gf2_exp[i] = x;
gf2_log[x] = i;
}
/* Invalid. */
log[0] = 0;
/* The loop above sets log[1] = 0xff, which is correct,
* but log[1] = 0 is nicer. */
log[1] = 0;
gf2_log[0] = 0;
/* The loop above sets gf2_log[1] = 0xff, which is correct,
* but gf2_log[1] = 0 is nicer. */
gf2_log[1] = 0;
}
static unsigned
mult(unsigned a, unsigned b)
{
return (a && b) ? ilog[ (log[a] + log[b]) % 255] : 0;
return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0;
}
static unsigned
invert(unsigned x)
{
return x ? ilog[0xff - log[x]] : 0;
return x ? gf2_exp[0xff - gf2_log[x]] : 0;
}
static unsigned
......@@ -108,7 +103,7 @@ compute_dtable(void)
{
unsigned s = sbox[i];
unsigned j;
uint32_t t =( ( (s ^ xtime(s)) << 24)
unsigned long t =( ( (s ^ xtime(s)) << 24)
| (s << 16) | (s << 8)
| xtime(s) );
......@@ -127,18 +122,36 @@ compute_itable(void)
{
unsigned s = isbox[i];
unsigned j;
uint32_t t = ( (mult(s, 0xb) << 24)
| (mult(s, 0xd) << 16)
| (mult(s, 0x9) << 8)
| (mult(s, 0xe) ));
unsigned long t = ( (mult(s, 0xb) << 24)
| (mult(s, 0xd) << 16)
| (mult(s, 0x9) << 8)
| (mult(s, 0xe) ));
for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
itable[j][i] = t;
}
}
/* Used for key inversion, inverse mix column. No sbox. */
static void
display_byte_table(const char *name, uint8_t *table)
compute_mtable(void)
{
unsigned i;
for (i = 0; i<0x100; i++)
{
unsigned j;
unsigned long t = ( (mult(i, 0xb) << 24)
| (mult(i, 0xd) << 16)
| (mult(i, 0x9) << 8)
| (mult(i, 0xe) ));
for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
mtable[j][i] = t;
}
}
static void
display_byte_table(const char *name, unsigned char *table)
{
unsigned i, j;
......@@ -155,7 +168,7 @@ display_byte_table(const char *name, uint8_t *table)
}
static void
display_table(const char *name, uint32_t table[][0x100])
display_table(const char *name, unsigned long table[][0x100])
{
unsigned i, j, k;
......@@ -188,8 +201,8 @@ main(int argc, char **argv)
compute_log();
if (argc == 1)
{
display_byte_table("log", log);
display_byte_table("ilog", ilog);
display_byte_table("gf2_log", gf2_log);
display_byte_table("gf2_exp", gf2_exp);
compute_sbox();
display_byte_table("sbox", sbox);
......@@ -200,7 +213,10 @@ main(int argc, char **argv)
compute_itable();
display_table("itable", itable);
compute_mtable();
display_table("mtable", mtable);
return 0;
}
else if (argc == 2)
......
/* arcfour-crypt.c
*
* The arcfour/rc4 stream cipher.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2001, 2004 Niels Mller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "arcfour.h"
void
arcfour_crypt(struct arcfour_ctx *ctx,
unsigned length, uint8_t *dst,
const uint8_t *src)
{
register uint8_t i, j;
register int si, sj;
i = ctx->i; j = ctx->j;
while(length--)
{
i++; i &= 0xff;
si = ctx->S[i];
j += si; j &= 0xff;
sj = ctx->S[i] = ctx->S[j];
ctx->S[j] = si;
*dst++ = *src++ ^ ctx->S[ (si + sj) & 0xff ];
}
ctx->i = i; ctx->j = j;
}
/* arcfour-meta.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2002 Niels Mller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "nettle-meta.h"
#include "arcfour.h"
const struct nettle_cipher nettle_arcfour128 =
{ "arcfour128", sizeof(struct arcfour_ctx),
0, 16,
(nettle_set_key_func) arcfour_set_key,
(nettle_set_key_func) arcfour_set_key,
(nettle_crypt_func) arcfour_crypt,
(nettle_crypt_func) arcfour_crypt
};
/* arcfour.c
*
* The arcfour/rc4 stream cipher.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2001 Niels Mller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
The arcfour/rc4 stream cipher.
Copyright (C) 2001, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
......@@ -35,7 +43,7 @@
void
arcfour_set_key(struct arcfour_ctx *ctx,
unsigned length, const uint8_t *key)
size_t length, const uint8_t *key)
{
unsigned i, j, k;
......@@ -57,8 +65,15 @@ arcfour_set_key(struct arcfour_ctx *ctx,
}
void
arcfour_stream(struct arcfour_ctx *ctx,
unsigned length, uint8_t *dst)
arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key)
{
arcfour_set_key (ctx, ARCFOUR128_KEY_SIZE, key);
}
void
arcfour_crypt(struct arcfour_ctx *ctx,
size_t length, uint8_t *dst,
const uint8_t *src)
{
register uint8_t i, j;
register int si, sj;
......@@ -71,8 +86,7 @@ arcfour_stream(struct arcfour_ctx *ctx,
j += si; j &= 0xff;
sj = ctx->S[i] = ctx->S[j];
ctx->S[j] = si;
*dst++ = ctx->S[ (si + sj) & 0xff ];
*dst++ = *src++ ^ ctx->S[ (si + sj) & 0xff ];
}
ctx->i = i; ctx->j = j;
}
/* arcfour.h
*
* The arcfour/rc4 stream cipher.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2001 Niels Mller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
The arcfour/rc4 stream cipher.
Copyright (C) 2001, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_ARCFOUR_H_INCLUDED
#define NETTLE_ARCFOUR_H_INCLUDED
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define arcfour128_set_key nettle_arcfour128_set_key
#define arcfour_set_key nettle_arcfour_set_key
#define arcfour_crypt nettle_arcfour_crypt
#define arcfour_stream nettle_arcfour_stream
/* Minimum and maximum keysizes, and a reasonable default. In
* octets.*/
#define ARCFOUR_MIN_KEY_SIZE 1
#define ARCFOUR_MAX_KEY_SIZE 256
#define ARCFOUR_KEY_SIZE 16
#define ARCFOUR128_KEY_SIZE 16
struct arcfour_ctx
{
......@@ -48,16 +61,19 @@ struct arcfour_ctx
void
arcfour_set_key(struct arcfour_ctx *ctx,
unsigned length, const uint8_t *key);
size_t length, const uint8_t *key);
void
arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key);
void
arcfour_crypt(struct arcfour_ctx *ctx,
unsigned length, uint8_t *dst,
size_t length, uint8_t *dst,
const uint8_t *src);
void
arcfour_stream(struct arcfour_ctx *ctx,
unsigned length, uint8_t *dst);
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_ARCFOUR_H_INCLUDED */
/* arctwo-meta.c
Copyright (C) 2004 Simon Josefsson
Copyright (C) 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "nettle-meta.h"
#include "arctwo.h"
#define ARCTWO(bits) { \
"arctwo" #bits, sizeof (struct arctwo_ctx), \
ARCTWO_BLOCK_SIZE, bits/8, \
(nettle_set_key_func *) arctwo ## bits ## _set_key, \
(nettle_set_key_func *) arctwo ## bits ## _set_key, \
(nettle_cipher_func *) arctwo_encrypt, \
(nettle_cipher_func *) arctwo_decrypt, \
}
const struct nettle_cipher nettle_arctwo40
= ARCTWO(40);
const struct nettle_cipher nettle_arctwo64
= ARCTWO(64);
const struct nettle_cipher nettle_arctwo128
= ARCTWO(128);
/* Gutmann variant. */
const struct nettle_cipher nettle_arctwo_gutmann128 =
{
"arctwo_gutmann128", sizeof (struct arctwo_ctx),
ARCTWO_BLOCK_SIZE, 16,
(nettle_set_key_func *) arctwo128_set_key_gutmann,
(nettle_set_key_func *) arctwo128_set_key_gutmann,
(nettle_cipher_func *) arctwo_encrypt,
(nettle_cipher_func *) arctwo_decrypt,
};
/* arctwo.c
The cipher described in rfc2268; aka Ron's Cipher 2.
Copyright (C) 2004 Simon Josefsson
Copyright (C) 2003 Nikos Mavroyanopoulos
Copyright (C) 2004 Free Software Foundation, Inc.
Copyright (C) 2004, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
* as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
* direct use by Libgcrypt by Werner Koch and later adapted for direct
* use by Nettle by Simon Josefsson and Niels Möller.
*
* The implementation here is based on Peter Gutmann's RRC.2 paper and
* RFC 2268.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "arctwo.h"
#include "macros.h"
static const uint8_t arctwo_sbox[] = {
0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad
};
#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n))))
#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n))))
void
arctwo_encrypt (struct arctwo_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE)
{
register unsigned i;
uint16_t w0, w1, w2, w3;
w0 = LE_READ_UINT16 (&src[0]);
w1 = LE_READ_UINT16 (&src[2]);
w2 = LE_READ_UINT16 (&src[4]);
w3 = LE_READ_UINT16 (&src[6]);
for (i = 0; i < 16; i++)
{
register unsigned j = i * 4;
/* For some reason I cannot combine those steps. */
w0 += (w1 & ~w3) + (w2 & w3) + ctx->S[j];
w0 = rotl16 (w0, 1);
w1 += (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1];
w1 = rotl16 (w1, 2);
w2 += (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2];
w2 = rotl16 (w2, 3);
w3 += (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3];
w3 = rotl16 (w3, 5);
if (i == 4 || i == 10)
{
w0 += ctx->S[w3 & 63];
w1 += ctx->S[w0 & 63];
w2 += ctx->S[w1 & 63];
w3 += ctx->S[w2 & 63];
}
}
LE_WRITE_UINT16 (&dst[0], w0);
LE_WRITE_UINT16 (&dst[2], w1);
LE_WRITE_UINT16 (&dst[4], w2);
LE_WRITE_UINT16 (&dst[6], w3);
}
}
void
arctwo_decrypt (struct arctwo_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE)
{
register unsigned i;
uint16_t w0, w1, w2, w3;
w0 = LE_READ_UINT16 (&src[0]);
w1 = LE_READ_UINT16 (&src[2]);
w2 = LE_READ_UINT16 (&src[4]);
w3 = LE_READ_UINT16 (&src[6]);
for (i = 16; i-- > 0; )
{
register unsigned j = i * 4;
w3 = rotr16 (w3, 5);
w3 -= (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3];
w2 = rotr16 (w2, 3);
w2 -= (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2];
w1 = rotr16 (w1, 2);
w1 -= (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1];
w0 = rotr16 (w0, 1);
w0 -= (w1 & ~w3) + (w2 & w3) + ctx->S[j];
if (i == 5 || i == 11)
{
w3 = w3 - ctx->S[w2 & 63];
w2 = w2 - ctx->S[w1 & 63];
w1 = w1 - ctx->S[w0 & 63];
w0 = w0 - ctx->S[w3 & 63];
}
}
LE_WRITE_UINT16 (&dst[0], w0);
LE_WRITE_UINT16 (&dst[2], w1);
LE_WRITE_UINT16 (&dst[4], w2);
LE_WRITE_UINT16 (&dst[6], w3);
}
}
void
arctwo_set_key_ekb (struct arctwo_ctx *ctx,
size_t length, const uint8_t *key, unsigned ekb)
{
size_t i;
/* Expanded key, treated as octets */
uint8_t S[128];
uint8_t x;
assert (length >= ARCTWO_MIN_KEY_SIZE);
assert (length <= ARCTWO_MAX_KEY_SIZE);
assert (ekb <= 1024);
for (i = 0; i < length; i++)
S[i] = key[i];
/* Phase 1: Expand input key to 128 bytes */
for (i = length; i < ARCTWO_MAX_KEY_SIZE; i++)
S[i] = arctwo_sbox[(S[i - length] + S[i - 1]) & 255];
S[0] = arctwo_sbox[S[0]];
/* Reduce effective key size to ekb bits, if requested by caller. */
if (ekb > 0 && ekb < 1024)
{
int len = (ekb + 7) >> 3;
i = 128 - len;
x = arctwo_sbox[S[i] & (255 >> (7 & -ekb))];
S[i] = x;
while (i--)
{
x = arctwo_sbox[x ^ S[i + len]];
S[i] = x;
}
}
/* Make the expanded key endian independent. */
for (i = 0; i < 64; i++)
ctx->S[i] = LE_READ_UINT16(S + i * 2);
}
void
arctwo_set_key (struct arctwo_ctx *ctx, size_t length, const uint8_t *key)
{
arctwo_set_key_ekb (ctx, length, key, 8 * length);
}
void
arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
size_t length, const uint8_t *key)
{
arctwo_set_key_ekb (ctx, length, key, 0);
}
void
arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
{
arctwo_set_key_ekb (ctx, 5, key, 40);
}
void
arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
{
arctwo_set_key_ekb (ctx, 8, key, 64);
}
void
arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key)
{
arctwo_set_key_ekb (ctx, 16, key, 128);
}
void
arctwo128_set_key_gutmann (struct arctwo_ctx *ctx,
const uint8_t *key)
{
arctwo_set_key_ekb (ctx, 16, key, 1024);
}
/* arctwo.h
The arctwo/rfc2268 block cipher.
Copyright (C) 2004 Simon Josefsson
Copyright (C) 2002, 2004, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_ARCTWO_H_INCLUDED
#define NETTLE_ARCTWO_H_INCLUDED
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define arctwo_set_key nettle_arctwo_set_key
#define arctwo_set_key_ekb nettle_arctwo_set_key_ekb
#define arctwo_set_key_gutmann nettle_arctwo_set_key_gutmann
#define arctwo40_set_key nettle_arctwo40_set_key
#define arctwo64_set_key nettle_arctwo64_set_key
#define arctwo128_set_key nettle_arctwo128_set_key
#define arctwo128_set_key_gutmann nettle_arctwo128_set_key_gutmann
#define arctwo_encrypt nettle_arctwo_encrypt
#define arctwo_decrypt nettle_arctwo_decrypt
#define ARCTWO_BLOCK_SIZE 8
/* Variable key size from 1 byte to 128 bytes. */
#define ARCTWO_MIN_KEY_SIZE 1
#define ARCTWO_MAX_KEY_SIZE 128
#define ARCTWO_KEY_SIZE 8
struct arctwo_ctx
{
uint16_t S[64];
};
/* Key expansion function that takes the "effective key bits", 1-1024,
as an explicit argument. 0 means maximum key bits. */
void
arctwo_set_key_ekb (struct arctwo_ctx *ctx,
size_t length, const uint8_t * key, unsigned ekb);
/* Equvivalent to arctwo_set_key_ekb, with ekb = 8 * length */
void
arctwo_set_key (struct arctwo_ctx *ctx, size_t length, const uint8_t *key);
void
arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key);
void
arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key);
void
arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key);
/* Equvivalent to arctwo_set_key_ekb, with ekb = 1024 */
void
arctwo_set_key_gutmann (struct arctwo_ctx *ctx,
size_t length, const uint8_t *key);
void
arctwo128_set_key_gutmann (struct arctwo_ctx *ctx,
const uint8_t *key);
void
arctwo_encrypt (struct arctwo_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src);
void
arctwo_decrypt (struct arctwo_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src);
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_ARCTWO_H_INCLUDED */
Currently, code in this directory is written for arm cortex-a9.
For efficient loads and stores, use ldmia, stmia and friends. Can do
two loads or stores per cycle with 8-byte aligned addresses, or three
loads or stores in two cycles, regardless of alignment.
12 usable registers (if we exclude r9).
ABI gnueabi(hf) (not depending on the floating point conventions)
Registers May be Argument
clobbered number
r0 Y 1
r1 Y 2
r2 Y 3
r3 Y 4
r4 N
r5 N
r6 N
r7 N
r8 N
r9 (sl)
r10 N
r11 N
r12 (ip) Y
r13 (sp)
r14 (lr) N
r15 (pc)
q0 (d0, d1) Y 1 (for "hf" abi)
q1 (d2, d3) Y 2
q2 (d4, d5) Y 3
q3 (d6, d7) Y 4
q4 (d8, d9) N
q5 (d10, d11) N
q6 (d12, d13) N
q7 (d14, d15) N
q8 (d16, d17) Y
q9 (d18, d19) Y
q10 (d20, d21) Y
q11 (d22, d23) Y
q12 (d24, d25) Y
q13 (d26, d27) Y
q14 (d28, d29) Y
q15 (d30, d31) Y
Endianness
ARM supports big- and little-endian memory access modes. Representation in
registers stays the same but loads and stores switch bytes. This has to be
taken into account in various cases.
Two m4 macros are provided to handle these special cases in assembly source:
IF_LE(<if-true>,<if-false>)
IF_BE(<if-true>,<if-false>)
respectively expand to <if-true> if the target system's endianness is
little-endian or big-endian. Otherwise they expand to <if-false>.
1. ldr/str
Loading and storing 32-bit words will reverse the words' bytes in little-endian
mode. If the handled data is actually a byte sequence or data in network byte
order (big-endian), the loaded word needs to be reversed after load to get it
back into correct sequence. See v6/sha1-compress.asm LOAD macro for example.
2. shifts
If data is to be processed with bit operations only, endianness can be ignored
because byte-swapping on load and store will cancel each other out. Shifts
however have to be inverted. See arm/memxor.asm for an example.
3. v{ld,st}1.{8,32}
NEON's vld instruction can be used to produce endianness-neutral code. vld1.8
will load a byte sequence into a register regardless of memory endianness. This
can be used to process byte sequences. See arm/neon/umac-nh.asm for example.
In the same fashion, vst1.8 can be used do a little-endian store. See
arm/neon/salsa and chacha routines for examples.
NOTE: vst1.x (at least on the Allwinner A20 Cortex-A7 implementation) seems to
interfer with itself on subsequent calls, slowing it down. This can be avoided
by putting calculcations or loads inbetween two vld1.x stores.
Similarly, vld1.32 is used in chacha and salsa routines where 32-bit operands
are stored in host-endianness in RAM but need to be loaded sequentially without
the distortion introduced by vldm/vstm. Consecutive vld1.x instructions do not
seem to suffer from slowdown similar to vst1.x.
4. vldm/vstm
Care has to be taken when using vldm/vstm because they have two non-obvious
characteristics:
a. vldm/vstm do normal byte-swapping on each value they load. When loading into
d (doubleword) registers, this means that bytes, halfwords and words of the
doubleword get swapped. When the data loaded actually represents e.g.
vectors of 32-bit words this will swap columns.
a. vldm/vstm on q (quadword) registers get translated into lvdm/vstm on the
equivalent number of d (doubleword) registers. Instead of a 128-bit load it
does two 64-bit loads. When again handling vectors of 32-bit words this will
still swap adjacent columns but will not reverse all four columns.
memory adr0: w0 w1 w2 w3
register q0: w1 w0 w3 w2
See arm/neon/chacha-core-internal.asm for an example.
5. simple byte store
Sometimes it is necessary to store remaining single bytes to memory. A simple
logic will store the lowest byte from a register, then do a right shift and
start over until all bytes are stored. Since this constitutes a
least-significant-byte-first store, the data to be stored needs to be reversed
first on a big-endian system. See arm/memxor.asm Lmemxor_leftover for an
example.
6. Function parameters/return values
AAPCS requires 64-bit parameters to be passed to and returned from functions
"in two consecutive registers [...] as if the value had been loaded from memory
representation with a single LDM instruction." Since loading a big-endian
doubleword using ldm transposes its words, the same has to be done when e.g.
returning a 64-bit value from an assembler routine. See arm/neon/umac-nh.asm
for an example.
C arm/aes-decrypt-internal.asm
ifelse(`
Copyright (C) 2013 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
')
include_src(`arm/aes.m4')
define(`PARAM_ROUNDS', `r0')
define(`PARAM_KEYS', `r1')
define(`TABLE', `r2')
define(`PARAM_LENGTH', `r3')
C On stack: DST, SRC
define(`W0', `r4')
define(`W1', `r5')
define(`W2', `r6')
define(`W3', `r7')
define(`T0', `r8')
define(`COUNT', `r10')
define(`KEY', `r11')
define(`MASK', `r0') C Overlaps inputs, except TABLE
define(`X0', `r1')
define(`X1', `r3')
define(`X2', `r12')
define(`X3', `r14') C lr
define(`FRAME_ROUNDS', `[sp]')
define(`FRAME_KEYS', `[sp, #+4]')
define(`FRAME_LENGTH', `[sp, #+8]')
C 8 saved registers
define(`FRAME_DST', `[sp, #+44]')
define(`FRAME_SRC', `[sp, #+48]')
define(`AES_DECRYPT_ROUND', `
and T0, MASK, $1, lsl #2
ldr $5, [TABLE, T0]
and T0, MASK, $2, lsl #2
ldr $6, [TABLE, T0]
and T0, MASK, $3, lsl #2
ldr $7, [TABLE, T0]
and T0, MASK, $4, lsl #2
ldr $8, [TABLE, T0]
and T0, MASK, $4, ror #6
add TABLE, TABLE, #1024
ldr T0, [TABLE, T0]
eor $5, $5, T0
and T0, MASK, $1, ror #6
ldr T0, [TABLE, T0]
eor $6, $6, T0
and T0, MASK, $2, ror #6
ldr T0, [TABLE, T0]
eor $7, $7, T0
and T0, MASK, $3, ror #6
ldr T0, [TABLE, T0]
eor $8, $8, T0
and T0, MASK, $3, ror #14
add TABLE, TABLE, #1024
ldr T0, [TABLE, T0]
eor $5, $5, T0
and T0, MASK, $4, ror #14
ldr T0, [TABLE, T0]
eor $6, $6, T0
and T0, MASK, $1, ror #14
ldr T0, [TABLE, T0]
eor $7, $7, T0
and T0, MASK, $2, ror #14
ldr T0, [TABLE, T0]
eor $8, $8, T0
and T0, MASK, $2, ror #22
add TABLE, TABLE, #1024
ldr T0, [TABLE, T0]
eor $5, $5, T0
and T0, MASK, $3, ror #22
ldr T0, [TABLE, T0]
eor $6, $6, T0
and T0, MASK, $4, ror #22
ldr T0, [TABLE, T0]
eor $7, $7, T0
and T0, MASK, $1, ror #22
ldr T0, [TABLE, T0]
ldm $9, {$1,$2,$3,$4}
eor $8, $8, T0
sub TABLE, TABLE, #3072
eor $5, $5, $1
eor $6, $6, $2
sub $9, $9, #16
eor $7, $7, $3
eor $8, $8, $4
')
.file "aes-decrypt-internal.asm"
C _aes_decrypt(unsigned rounds, const uint32_t *keys,
C const struct aes_table *T,
C size_t length, uint8_t *dst,
C uint8_t *src)
.text
ALIGN(4)
PROLOGUE(_nettle_aes_decrypt)
teq PARAM_LENGTH, #0
beq .Lend
push {r0,r1,r3, r4,r5,r6,r7,r8,r10,r11,lr}
mov MASK, #0x3fc
ALIGN(16)
.Lblock_loop:
ldr X0, FRAME_SRC C Use X0 as SRC pointer
ldm sp, {COUNT, KEY}
AES_LOAD(X0,KEY,W0)
AES_LOAD(X0,KEY,W1)
AES_LOAD(X0,KEY,W2)
AES_LOAD_INCR(X0,KEY,W3, -28)
str X0, FRAME_SRC
add TABLE, TABLE, #AES_TABLE0
b .Lentry
ALIGN(16)
.Lround_loop:
C Transform X -> W
AES_DECRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY)
.Lentry:
subs COUNT, COUNT,#2
C Transform W -> X
AES_DECRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY)
bne .Lround_loop
lsr COUNT, MASK, #2 C Put the needed mask in the unused COUNT register
sub TABLE, TABLE, #AES_TABLE0
C Final round
AES_FINAL_ROUND_V5(X0, X3, X2, X1, KEY, W0, COUNT)
AES_FINAL_ROUND_V5(X1, X0, X3, X2, KEY, W1, COUNT)
AES_FINAL_ROUND_V5(X2, X1, X0, X3, KEY, W2, COUNT)
AES_FINAL_ROUND_V5(X3, X2, X1, X0, KEY, W3, COUNT)
ldr X0, FRAME_DST
ldr X1, FRAME_LENGTH
AES_STORE(X0,W0)
AES_STORE(X0,W1)
AES_STORE(X0,W2)
AES_STORE(X0,W3)
subs X1, X1, #16
str X0, FRAME_DST
str X1, FRAME_LENGTH
bhi .Lblock_loop
add sp, sp, #12 C Drop saved r0, r1, r3
pop {r4,r5,r6,r7,r8,r10,r11,pc}
.Lend:
bx lr
EPILOGUE(_nettle_aes_decrypt)
C arm/aes-encrypt-internal.asm
ifelse(`
Copyright (C) 2013 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
')
include_src(`arm/aes.m4')
C Benchmarked at at 725, 815, 990 cycles/block on cortex A9,
C for 128, 192 and 256 bit key sizes.
C Possible improvements: More efficient load and store with
C aligned accesses. Better scheduling.
define(`PARAM_ROUNDS', `r0')
define(`PARAM_KEYS', `r1')
define(`TABLE', `r2')
define(`PARAM_LENGTH', `r3')
C On stack: DST, SRC
define(`W0', `r4')
define(`W1', `r5')
define(`W2', `r6')
define(`W3', `r7')
define(`T0', `r8')
define(`COUNT', `r10')
define(`KEY', `r11')
define(`MASK', `r0') C Overlaps inputs, except TABLE
define(`X0', `r1')
define(`X1', `r3')
define(`X2', `r12')
define(`X3', `r14') C lr
define(`FRAME_ROUNDS', `[sp]')
define(`FRAME_KEYS', `[sp, #+4]')
define(`FRAME_LENGTH', `[sp, #+8]')
C 8 saved registers
define(`FRAME_DST', `[sp, #+44]')
define(`FRAME_SRC', `[sp, #+48]')
C AES_ENCRYPT_ROUND(x0,x1,x2,x3,w0,w1,w2,w3,key)
C MASK should hold the constant 0x3fc.
define(`AES_ENCRYPT_ROUND', `
and T0, MASK, $1, lsl #2
ldr $5, [TABLE, T0]
and T0, MASK, $2, lsl #2
ldr $6, [TABLE, T0]
and T0, MASK, $3, lsl #2
ldr $7, [TABLE, T0]
and T0, MASK, $4, lsl #2
ldr $8, [TABLE, T0]
and T0, MASK, $2, ror #6
add TABLE, TABLE, #1024
ldr T0, [TABLE, T0]
eor $5, $5, T0
and T0, MASK, $3, ror #6
ldr T0, [TABLE, T0]
eor $6, $6, T0
and T0, MASK, $4, ror #6
ldr T0, [TABLE, T0]
eor $7, $7, T0
and T0, MASK, $1, ror #6
ldr T0, [TABLE, T0]
eor $8, $8, T0
and T0, MASK, $3, ror #14
add TABLE, TABLE, #1024
ldr T0, [TABLE, T0]
eor $5, $5, T0
and T0, MASK, $4, ror #14
ldr T0, [TABLE, T0]
eor $6, $6, T0
and T0, MASK, $1, ror #14
ldr T0, [TABLE, T0]
eor $7, $7, T0
and T0, MASK, $2, ror #14
ldr T0, [TABLE, T0]
eor $8, $8, T0
and T0, MASK, $4, ror #22
add TABLE, TABLE, #1024
ldr T0, [TABLE, T0]
eor $5, $5, T0
and T0, MASK, $1, ror #22
ldr T0, [TABLE, T0]
eor $6, $6, T0
and T0, MASK, $2, ror #22
ldr T0, [TABLE, T0]
eor $7, $7, T0
and T0, MASK, $3, ror #22
ldr T0, [TABLE, T0]
ldm $9!, {$1,$2,$3,$4}
eor $8, $8, T0
sub TABLE, TABLE, #3072
eor $5, $5, $1
eor $6, $6, $2
eor $7, $7, $3
eor $8, $8, $4
')
.file "aes-encrypt-internal.asm"
C _aes_encrypt(unsigned rounds, const uint32_t *keys,
C const struct aes_table *T,
C size_t length, uint8_t *dst,
C uint8_t *src)
.text
ALIGN(4)
PROLOGUE(_nettle_aes_encrypt)
teq PARAM_LENGTH, #0
beq .Lend
push {r0,r1,r3, r4,r5,r6,r7,r8,r10,r11,lr}
mov MASK, #0x3fc
ALIGN(16)
.Lblock_loop:
ldr X0, FRAME_SRC C Use X0 as SRC pointer
ldm sp, {COUNT, KEY}
AES_LOAD(X0,KEY,W0)
AES_LOAD(X0,KEY,W1)
AES_LOAD(X0,KEY,W2)
AES_LOAD(X0,KEY,W3)
str X0, FRAME_SRC
add TABLE, TABLE, #AES_TABLE0
b .Lentry
ALIGN(16)
.Lround_loop:
C Transform X -> W
AES_ENCRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY)
.Lentry:
subs COUNT, COUNT,#2
C Transform W -> X
AES_ENCRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY)
bne .Lround_loop
lsr COUNT, MASK, #2 C Put the needed mask in the unused COUNT register
sub TABLE, TABLE, #AES_TABLE0
C Final round
AES_FINAL_ROUND_V5(X0, X1, X2, X3, KEY, W0, COUNT)
AES_FINAL_ROUND_V5(X1, X2, X3, X0, KEY, W1, COUNT)
AES_FINAL_ROUND_V5(X2, X3, X0, X1, KEY, W2, COUNT)
AES_FINAL_ROUND_V5(X3, X0, X1, X2, KEY, W3, COUNT)
ldr X0, FRAME_DST
ldr X1, FRAME_LENGTH
AES_STORE(X0,W0)
AES_STORE(X0,W1)
AES_STORE(X0,W2)
AES_STORE(X0,W3)
subs X1, X1, #16
str X0, FRAME_DST
str X1, FRAME_LENGTH
bhi .Lblock_loop
add sp, sp, #12 C Drop saved r0, r1, r3
pop {r4,r5,r6,r7,r8,r10,r11,pc}
.Lend:
bx lr
EPILOGUE(_nettle_aes_encrypt)