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
Showing
with 2455 additions and 75 deletions
/* 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);
}
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if 1
# define BYTE_FORMAT "0x%02x"
# define BYTE_COLUMNS 8
#else
# define BYTE_FORMAT "%3d"
# define BYTE_COLUMNS 0x10
#endif
#define WORD_FORMAT "0x%08lx"
#define WORD_COLUMNS 4
unsigned char sbox[0x100];
unsigned char isbox[0x100];
unsigned char gf2_log[0x100];
unsigned char gf2_exp[0x100];
unsigned long dtable[4][0x100];
unsigned long itable[4][0x100];
unsigned long mtable[4][0x100];
static unsigned
xtime(unsigned x)
{
assert (x < 0x100);
x <<= 1;
if (x & 0x100)
x ^= 0x11b;
assert (x < 0x100);
return x;
}
/* Computes the exponentiatiom and logarithm tables for GF_2, to the
* base x+1 (0x03). The unit element is 1 (0x01).*/
static void
compute_log(void)
{
unsigned i = 0;
unsigned x = 1;
memset(gf2_log, 0, 0x100);
for (i = 0; i < 0x100; i++, x = x ^ xtime(x))
{
gf2_exp[i] = x;
gf2_log[x] = i;
}
/* Invalid. */
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) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0;
}
static unsigned
invert(unsigned x)
{
return x ? gf2_exp[0xff - gf2_log[x]] : 0;
}
static unsigned
affine(unsigned x)
{
return 0xff &
(0x63^x^(x>>4)^(x<<4)^(x>>5)^(x<<3)^(x>>6)^(x<<2)^(x>>7)^(x<<1));
}
static void
compute_sbox(void)
{
unsigned i;
for (i = 0; i<0x100; i++)
{
sbox[i] = affine(invert(i));
isbox[sbox[i]] = i;
}
}
/* Generate little endian tables, i.e. the first row of the AES state
* arrays occupies the least significant byte of the words.
*
* The sbox values are multiplied with the column of GF2 coefficients
* of the polynomial 03 x^3 + x^2 + x + 02. */
static void
compute_dtable(void)
{
unsigned i;
for (i = 0; i<0x100; i++)
{
unsigned s = sbox[i];
unsigned j;
unsigned long t =( ( (s ^ xtime(s)) << 24)
| (s << 16) | (s << 8)
| xtime(s) );
for (j = 0; j<4; j++, t = (t << 8) | (t >> 24))
dtable[j][i] = t;
}
}
/* The inverse sbox values are multiplied with the column of GF2 coefficients
* of the polynomial inverse 0b x^3 + 0d x^2 + 09 x + 0e. */
static void
compute_itable(void)
{
unsigned i;
for (i = 0; i<0x100; i++)
{
unsigned s = isbox[i];
unsigned j;
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
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;
printf("uint8_t %s[0x100] =\n{", name);
for (i = 0; i<0x100; i+= BYTE_COLUMNS)
{
printf("\n ");
for (j = 0; j<BYTE_COLUMNS; j++)
printf(BYTE_FORMAT ",", table[i + j]);
}
printf("\n};\n\n");
}
static void
display_table(const char *name, unsigned long table[][0x100])
{
unsigned i, j, k;
printf("uint32_t %s[4][0x100] =\n{\n ", name);
for (k = 0; k<4; k++)
{
printf("{ ");
for (i = 0; i<0x100; i+= WORD_COLUMNS)
{
printf("\n ");
for (j = 0; j<WORD_COLUMNS; j++)
printf(WORD_FORMAT ",", table[k][i + j]);
}
printf("\n },");
}
printf("\n};\n\n");
}
static void
display_polynomial(const unsigned *p)
{
printf("(%x x^3 + %x x^2 + %x x + %x)",
p[3], p[2], p[1], p[0]);
}
int
main(int argc, char **argv)
{
compute_log();
if (argc == 1)
{
display_byte_table("gf2_log", gf2_log);
display_byte_table("gf2_exp", gf2_exp);
compute_sbox();
display_byte_table("sbox", sbox);
display_byte_table("isbox", isbox);
compute_dtable();
display_table("dtable", dtable);
compute_itable();
display_table("itable", itable);
compute_mtable();
display_table("mtable", mtable);
return 0;
}
else if (argc == 2)
{
unsigned a;
for (a = 1; a<0x100; a++)
{
unsigned a1 = invert(a);
unsigned b;
unsigned u;
if (a1 == 0)
printf("invert(%x) = 0 !\n", a);
u = mult(a, a1);
if (u != 1)
printf("invert(%x) = %x; product = %x\n",
a, a1, u);
for (b = 1; b<0x100; b++)
{
unsigned b1 = invert(b);
unsigned c = mult(a, b);
if (c == 0)
printf("%x x %x = 0\n", a, b);
u = mult(c, a1);
if (u != b)
printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
a, b, c, a, a1, c, a1, u);
u = mult(c, b1);
if (u != a)
printf("%x x %x = %x, invert(%x) = %x, %x x %x = %x\n",
a, b, c, b, b1, c, b1, u);
}
}
return 0;
}
else if (argc == 4)
{
unsigned a, b, c;
int op = argv[2][0];
a = strtoul(argv[1], NULL, 16);
b = strtoul(argv[3], NULL, 16);
switch (op)
{
case '+':
c = a ^ b;
break;
case '*':
case 'x':
c = mult(a,b);
break;
case '/':
c = mult(a, invert(b));
break;
default:
return 1;
}
printf("%x %c %x = %x\n", a, op, b, c);
return 0;
}
#if 0
else if (argc == 5)
{
/* Compute gcd(a, x^4+1) */
unsigned d[4];
unsigned u[4];
for (i = 0; i<4; i++)
a[i] = strtoul(argv[1+i], NULL, 16);
}
#endif
else if (argc == 9)
{
unsigned a[4];
unsigned b[4];
unsigned c[4];
unsigned i;
for (i = 0; i<4; i++)
{
a[i] = strtoul(argv[1+i], NULL, 16);
b[i] = strtoul(argv[5+i], NULL, 16);
}
c[0] = mult(a[0],b[0])^mult(a[3],b[1])^mult(a[2],b[2])^mult(a[1],b[3]);
c[1] = mult(a[1],b[0])^mult(a[0],b[1])^mult(a[3],b[2])^mult(a[2],b[3]);
c[2] = mult(a[2],b[0])^mult(a[1],b[1])^mult(a[0],b[2])^mult(a[3],b[3]);
c[3] = mult(a[3],b[0])^mult(a[2],b[1])^mult(a[1],b[2])^mult(a[0],b[3]);
display_polynomial(a); printf(" * "); display_polynomial(b);
printf(" = "); display_polynomial(c); printf("\n");
}
return 1;
}
/* 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.
*/
#include "arcfour.h"
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"
#endif
#include <assert.h>
#include "arcfour.h"
#define SWAP(a,b) do { int _t = a; a = b; b = _t; } while(0)
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;
......@@ -52,39 +64,29 @@ arcfour_set_key(struct arcfour_ctx *ctx,
ctx->i = ctx->j = 0;
}
void
arcfour_crypt(struct arcfour_ctx *ctx,
unsigned length, uint8_t *dst,
const uint8_t *src)
arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key)
{
register uint8_t i, j;
i = ctx->i; j = ctx->j;
while(length--)
{
i++; i &= 0xff;
j += ctx->S[i]; j &= 0xff;
SWAP(ctx->S[i], ctx->S[j]);
*dst++ = *src++ ^ ctx->S[ (ctx->S[i] + ctx->S[j]) & 0xff ];
}
ctx->i = i; ctx->j = j;
arcfour_set_key (ctx, ARCFOUR128_KEY_SIZE, key);
}
void
arcfour_stream(struct arcfour_ctx *ctx,
unsigned length, uint8_t *dst)
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;
i = ctx->i; j = ctx->j;
while(length--)
{
i++; i &= 0xff;
j += ctx->S[i]; j &= 0xff;
SWAP(ctx->S[i], ctx->S[j]);
*dst++ = ctx->S[ (ctx->S[i] + ctx->S[j]) & 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.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 <inttypes.h>
#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
/* 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
{
......@@ -43,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)
C Loads one word, and adds it to the subkey. Uses T0
C AES_LOAD(SRC, KEY, REG, INCR)
define(`AES_LOAD_INCR', `
ldrb $3, [$1], #+1
ldrb T0, [$1], #+1
orr $3, T0, lsl #8
ldrb T0, [$1], #+1
orr $3, T0, lsl #16
ldrb T0, [$1], #+1
orr $3, T0, lsl #24
ldr T0, [$2], #$4
eor $3, T0
')
C Loads one word, and adds it to the subkey. Uses T0
C AES_LOAD(SRC, KEY, REG)
define(`AES_LOAD', `AES_LOAD_INCR($1, $2, $3, +4)')
C Stores one word. Destroys input.
C AES_STORE(DST, X)
define(`AES_STORE', `
strb $2, [$1], #+1
ror $2, $2, #8
strb $2, [$1], #+1
ror $2, $2, #8
strb $2, [$1], #+1
ror $2, $2, #8
strb $2, [$1], #+1
')
C AES_FINAL_ROUND_V6(a,b,c,d,key,res)
define(`AES_FINAL_ROUND_V6', `
uxtb T0, $1
ldrb $6, [TABLE, T0]
uxtb T0, $2, ror #8
ldrb T0, [TABLE, T0]
eor $6, $6, T0, lsl #8
uxtb T0, $3, ror #16
ldrb T0, [TABLE, T0]
eor $6, $6, T0, lsl #16
ldrb T0, [TABLE, $4, lsr #24]
eor $6, $6, T0, lsl #24
ldr T0, [$5], #+4
eor $6, $6, T0
')
C AES_FINAL_ROUND_V5(a,b,c,d,key,res,mask)
C Avoids the uxtb instruction, introduced in ARMv6.
C The mask argument should hold the constant 0xff
define(`AES_FINAL_ROUND_V5', `
and T0, $7, $1
ldrb $6, [TABLE, T0]
and T0, $7, $2, ror #8
ldrb T0, [TABLE, T0]
eor $6, $6, T0, lsl #8
and T0, $7, $3, ror #16
ldrb T0, [TABLE, T0]
eor $6, $6, T0, lsl #16
ldrb T0, [TABLE, $4, lsr #24]
eor $6, $6, T0, lsl #24
ldr T0, [$5], #+4
eor $6, T0
')
C arm/ecc-secp192r1-modp.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/.
')
.file "ecc-secp192r1-modp.asm"
.arm
define(`HP', `r0') C Overlaps unused modulo argument
define(`RP', `r1')
define(`XP', `r2')
define(`T0', `r3')
define(`T1', `r4')
define(`T2', `r5')
define(`T3', `r6')
define(`T4', `r7')
define(`T5', `r8')
define(`T6', `r10')
define(`T7', `r11')
define(`H0', `T0') C Overlaps T0 and T1
define(`H1', `T1')
define(`C2', `HP')
define(`C4', `r12')
C ecc_secp192r1_modp (const struct ecc_modulo *m, mp_limb_t *rp)
.text
.align 2
PROLOGUE(_nettle_ecc_secp192r1_modp)
push {r4,r5,r6,r7,r8,r10,r11}
C Reduce two words at a time
add HP, XP, #48
add XP, XP, #8
ldmdb HP!, {H0,H1}
ldm XP, {T2,T3,T4,T5,T6,T7}
mov C4, #0
adds T4, T4, H0
adcs T5, T5, H1
adcs T6, T6, H0
adcs T7, T7, H1
C Need to add carry to T2 and T4, do T4 later.
adc C4, C4, #0
ldmdb HP!, {H0,H1}
mov C2, #0
adcs T2, T2, H0
adcs T3, T3, H1
adcs T4, T4, H0
adcs T5, T5, H1
C Need to add carry to T0 and T2, do T2 later
adc C2, C2, #0
ldmdb XP!, {T0, T1}
adcs T0, T0, T6
adcs T1, T1, T7
adcs T2, T2, T6
adcs T3, T3, T7
adc C4, C4, #0
adds T2, T2, C2
adcs T3, T3, #0
adcs T4, T4, C4
adcs T5, T5, #0
mov C2, #0
adc C2, C2, #0
C Add in final carry
adcs T0, T0, #0
adcs T1, T1, #0
adcs T2, T2, C2
adcs T3, T3, #0
adcs T4, T4, #0
adc T5, T5, #0
stm RP, {T0,T1,T2,T3,T4,T5}
pop {r4,r5,r6,r7,r8,r10,r11}
bx lr
EPILOGUE(_nettle_ecc_secp192r1_modp)
C arm/ecc-secp224r1-modp.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/.
')
.file "ecc-secp224r1-modp.asm"
.arm
define(`RP', `r1') C Overlaps T0
define(`XP', `r2')
define(`H', `r0') C Overlaps unused modulo argument
define(`T0', `r1')
define(`T1', `r3')
define(`T2', `r4')
define(`T3', `r5')
define(`T4', `r6')
define(`T5', `r7')
define(`T6', `r8')
define(`N3', `r10')
define(`L0', `r11')
define(`L1', `r12')
define(`L2', `lr')
C ecc_secp224r1_modp (const struct ecc_modulo *m, mp_limb_t *rp)
.text
.align 2
PROLOGUE(_nettle_ecc_secp224r1_modp)
C Pushes RP last
push {r1,r4,r5,r6,r7,r8,r10,r11,lr}
add L2, XP, #28
ldm L2, {T0,T1,T2,T3,T4,T5,T6}
mov H, #0
adds T0, T0, T4
adcs T1, T1, T5
adcs T2, T2, T6
adc H, H, #0
C This switch from adcs to sbcs takes carry into account with
C correct sign, but it always subtracts 1 too much. We arrange
C to also add B^7 + 1 below, so the effect is adding p. This
C addition of p also ensures that the result never is
C negative.
sbcs N3, T3, T0
sbcs T4, T4, T1
sbcs T5, T5, T2
sbcs T6, T6, H
mov H, #1 C This is the B^7
sbc H, #0
subs T6, T6, T3
sbc H, #0
C Now subtract from low half
ldm XP!, {L0,L1,L2}
C Clear carry, with the sbcs, this is the 1.
adds XP, #0
sbcs T0, L0, T0
sbcs T1, L1, T1
sbcs T2, L2, T2
ldm XP!, {T3,L0,L1,L2}
sbcs T3, T3, N3
sbcs T4, L0, T4
sbcs T5, L1, T5
sbcs T6, L2, T6
rsc H, H, #0
C Now -2 <= H <= 0 is the borrow, so subtract (B^3 - 1) |H|
C Use (B^3 - 1) H = <H, H, H> if -1 <=H <= 0, and
C (B^3 - 1) H = <1,B-1, B-1, B-2> if H = -2
subs T0, T0, H
asr L1, H, #1
sbcs T1, T1, L1
eor H, H, L1
sbcs T2, T2, L1
sbcs T3, T3, H
sbcs T4, T4, #0
sbcs T5, T5, #0
sbcs T6, T6, #0
sbcs H, H, H
pop {XP} C Original RP
C Final borrow, subtract (B^3 - 1) |H|
subs T0, T0, H
sbcs T1, T1, H
sbcs T2, T2, H
sbcs T3, T3, #0
sbcs T4, T4, #0
sbcs T5, T5, #0
sbcs T6, T6, #0
stm XP, {T0,T1,T2,T3,T4,T5,T6}
pop {r4,r5,r6,r7,r8,r10,r11,pc}
EPILOGUE(_nettle_ecc_secp224r1_modp)
C arm/ecc-secp256r1-redc.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/.
')
.file "ecc-secp256r1-redc.asm"
.arm
define(`RP', `r1') C Overlaps T1 below
define(`XP', `r2')
define(`T0', `r0') C Overlaps unused modulo argument
define(`T1', `r1')
define(`T2', `r3')
define(`T3', `r4')
define(`T4', `r5')
define(`T5', `r6')
define(`T6', `r7')
define(`T7', `r8')
define(`F0', `r10')
define(`F1', `r11')
define(`F2', `r12')
define(`F3', `lr')
C ecc_secp256r1_redc (const struct ecc_modulo *m, mp_limb_t *rp)
.text
.align 2
PROLOGUE(_nettle_ecc_secp256r1_redc)
C Pushes RP last
push {r1, r4,r5,r6,r7,r8,r10,r11,lr}
ldm XP!, {T0,T1,T2,T3,T4,T5,T6,T7}
C Set <F3,F2,F1> to the high 4 limbs of (B^2-B+1)<T2,T1,T0>
C T2 T1
C T2 T1 T0
C - T2 T1 T0
C -------------
C F3 F2 F1 F0
adds F1, T0, T2
adcs F2, T1, #0
adc F3, T2, #0
subs F0, T1, T0
sbcs F1, F1, T1 C Could also be rsc ?
sbcs F2, F2, T2
sbc F3, F3, #0
C Add:
C T10 T9 T8 T7 T6 T5 T4 T3
C + F3 F2 F1 F0 T0 T2 T1 T0
C --------------------------
C T7 T6 T5 T4 T3 T2 T1 T0
adds T3, T3, T0
adcs T1, T4, T1
adcs T2, T5, T2
adcs T6, T6, T0
mov T0, T3 C FIXME: Be more clever?
mov T3, T6
adcs T4, T7, F0
ldm XP!, {T5,T6,T7}
adcs T5, T5, F1
adcs T6, T6, F2
adcs T7, T7, F3
C New F3, F2, F1, F0, also adding in carry
adcs F1, T0, T2
adcs F2, T1, #0
adc F3, T2, #0
subs F0, T1, T0
sbcs F1, F1, T1 C Could also be rsc ?
sbcs F2, F2, T2
sbc F3, F3, #0
C Start adding
adds T3, T3, T0
adcs T1, T4, T1
adcs T2, T5, T2
adcs T6, T6, T0
mov T0, T3 C FIXME: Be more clever?
mov T3, T6
adcs T4, T7, F0
ldm XP!, {T5,T6,T7}
adcs T5, T5, F1
adcs T6, T6, F2
adcs T7, T7, F3
C Final iteration, eliminate only T0, T1
C Set <F2, F1, F0> to the high 3 limbs of (B^2-B+1)<T1,T0>
C T1 T0 T1
C - T1 T0
C -------------
C F2 F1 F0
C First add in carry
adcs F1, T0, #0
adcs F2, T1, #0
subs F0, T1, T0
sbcs F1, F1, T1
sbc F2, F2, #0
C Add:
C T9 T8 T7 T6 T5 T4 T3 T2
C + F2 F1 F0 T0 0 T1 T0 0
C --------------------------
C F2 F1 T7 T6 T5 T4 T3 T2
adds T3, T3, T0
adcs T4, T4, T1
adcs T5, T5, #0
adcs T6, T6, T0
adcs T7, T7, F0
ldm XP!, {T0, T1}
mov F3, #0
adcs F1, F1, T0
adcs F2, F2, T1
C Sum is < B^8 + p, so it's enough to fold carry once,
C If carry, add in
C B^7 - B^6 - B^3 + 1 = <0, B-2, B-1, B-1, B-1, 0, 0, 1>
C Mask from carry flag, leaving carry intact
adc F3, F3, #0
rsb F3, F3, #0
pop {XP} C Original RP
adcs T0, T2, #0
adcs T1, T3, #0
adcs T2, T4, #0
adcs T3, T5, F3
adcs T4, T6, F3
adcs T5, T7, F3
and F3, F3, #-2
adcs T6, F1, F3
adcs T7, F2, #0
stm XP, {T0,T1,T2,T3,T4,T5,T6,T7}
pop {r4,r5,r6,r7,r8,r10,r11,pc}
EPILOGUE(_nettle_ecc_secp256r1_redc)
C arm/ecc-secp384r1-modp.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/.
')
.file "ecc-secp384r1-modp.asm"
.arm
define(`RP', `r1')
define(`XP', `r2')
define(`T0', `r0')
define(`T1', `r3')
define(`T2', `r4')
define(`T3', `r5')
define(`F0', `r6')
define(`F1', `r7')
define(`F2', `r8')
define(`F3', `r10')
define(`F4', `r11')
define(`N', `r12')
define(`H', `lr')
C ecc_secp384r1_modp (const struct ecc_modulo *m, mp_limb_t *rp)
.text
.align 2
PROLOGUE(_nettle_ecc_secp384r1_modp)
push {r4,r5,r6,r7,r8,r10,r11,lr}
add XP, XP, #80
ldm XP, {T0, T1, T2, T3} C 20-23
C First get top 4 limbs, which need folding twice, as
C
C T3 T2 T1 T0
C T3 T2 T1
C -T3
C ----------------
C F4 F3 F2 F1 F0
C
C Start with
C
C T3 T1 T0
C T1
C -T3
C -----------
C F2 F1 F0 Always fits
adds F0, T0, T1
adcs F1, T1, #0
adcs F2, T3, #0
subs F0, F0, T3
sbcs F1, F1, #0
sbcs F2, F2, #0
C T3 T2 T2 0
C F2 F1 F0
C ----------------
C F4 F3 F2 F1 F0
mov F4, #0
adds F1, F1, T2
adcs F2, F2, T2
adcs F3, T3, #0
adcs F4, F4, #0
C Add in to high part
sub XP, XP, #32
ldm XP, {T0, T1, T2, T3} C 12-15
mov H, #0
adds F0, T0, F0
adcs F1, T1, F1
adcs F2, T2, F2
adcs F3, T3, F3
adcs F4, F4, #0 C Do F4 later
C Add to low part, keeping carry (positive or negative) in H
sub XP, XP, #48
ldm XP, {T0, T1, T2, T3} C 0-3
mov H, #0
adds T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
adcs T3, T3, F3
adc H, H, #0
subs T1, T1, F0
sbcs T2, T2, F1
sbcs T3, T3, F2
sbc H, H, #0
adds T3, T3, F0
adc H, H, #0
stm XP!, {T0,T1,T2,T3} C 0-3
mov N, #2
.Loop:
ldm XP, {T0,T1,T2,T3} C 4-7
C First, propagate carry
adds T0, T0, H
asr H, #31 C Sign extend
adcs T1, T1, H
adcs T2, T2, H
adcs T3, T3, H
adc H, H, #0
C +B^4 term
adds T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
adcs T3, T3, F3
adc H, H, #0
C +B^3 terms
ldr F0, [XP, #+48] C 16
adds T0, T0, F1
adcs T1, T1, F2
adcs T2, T2, F3
adcs T3, T3, F0
adc H, H, #0
C -B
ldr F1, [XP, #+52] C 17-18
ldr F2, [XP, #+56]
subs T0, T0, F3
sbcs T1, T1, F0
sbcs T2, T2, F1
sbcs T3, T3, F2
sbcs H, H, #0
C +1
ldr F3, [XP, #+60] C 19
adds T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
adcs T3, T3, F3
adc H, H, #0
subs N, N, #1
stm XP!, {T0,T1,T2,T3}
bne .Loop
C Fold high limbs, we need to add in
C
C F4 F4 0 -F4 F4 H H 0 -H H
C
C We always have F4 >= 0, but we can have H < 0.
C Sign extension gets tricky when F4 = 0 and H < 0.
sub XP, XP, #48
ldm XP, {T0,T1,T2,T3} C 0-3
C H H 0 -H H
C ----------------
C S H F3 F2 F1 F0
C
C Define S = H >> 31 (asr), we then have
C
C F0 = H
C F1 = S - H
C F2 = - [H > 0]
C F3 = H - [H > 0]
C H = H + S
C
C And we get underflow in S - H iff H > 0
C H = 0 H > 0 H = -1
mov F0, H C 0 H -1
asr H, #31
subs F1, H, F0 C 0,C=1 -H,C=0 0,C=1
sbc F2, F2, F2 C 0 -1 0
sbc F3, F0, #0 C 0 H-1 -1
adds T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
adcs T3, T3, F3
adc H, H, F0 C 0+cy H+cy -2+cy
stm XP!, {T0,T1,T2,T3} C 0-3
ldm XP, {T0,T1,T2,T3} C 4-7
C F4 0 -F4
C ---------
C F3 F2 F1
rsbs F1, F4, #0
sbc F2, F2, F2
sbc F3, F4, #0
C Sign extend H
adds F0, F4, H
asr H, H, #31
adcs F1, F1, H
adcs F2, F2, H
adcs F3, F3, H
adcs F4, F4, H
adc H, H, #0
adds T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
adcs T3, T3, F3
stm XP!, {T0,T1,T2,T3} C 4-7
ldm XP, {T0,T1,T2,T3} C 8-11
adcs T0, T0, F4
adcs T1, T1, H
adcs T2, T2, H
adcs T3, T3, H
adc H, H, #0
stm XP, {T0,T1,T2,T3} C 8-11
C Final (unlikely) carry
sub XP, XP, #32
ldm XP!, {T0,T1,T2,T3} C 0-3
C Fold H into F0-F4
mov F0, H
asr H, #31
subs F1, H, F0
sbc F2, F2, F2
sbc F3, F0, #0
add F4, F0, H
adds T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
adcs T3, T3, F3
stm RP!, {T0,T1,T2,T3} C 0-3
ldm XP!, {T0,T1,T2,T3} C 4-7
adcs T0, T0, F4
adcs T1, T1, H
adcs T2, T2, H
adcs T3, T3, H
stm RP!, {T0,T1,T2,T3} C 4-7
ldm XP, {T0,T1,T2,T3} C 8-11
adcs T0, T0, H
adcs T1, T1, H
adcs T2, T2, H
adcs T3, T3, H
stm RP, {T0,T1,T2,T3} C 8-11
pop {r4,r5,r6,r7,r8,r10,r11,pc}
EPILOGUE(_nettle_ecc_secp384r1_modp)
C arm/ecc-secp521r1-modp.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/.
')
.file "ecc-secp521r1-modp.asm"
.arm
define(`HP', `r0')
define(`RP', `r1')
define(`XP', `r2')
define(`T0', `r3')
define(`T1', `r4')
define(`T2', `r5')
define(`F0', `r6')
define(`F1', `r7')
define(`F2', `r8')
define(`F3', `r10')
define(`H', `r12')
define(`N', `lr')
C ecc_secp521r1_modp (const struct ecc_modulo *m, mp_limb_t *rp)
.text
.Lc511:
.int 511
.align 2
PROLOGUE(_nettle_ecc_secp521r1_modp)
push {r4,r5,r6,r7,r8,r10,lr}
C Use that B^17 = 2^23 (mod p)
ldr F3, [XP, #+68] C 17
add HP, XP, #72 C 18
ldr T0, [XP] C 0
adds T0, T0, F3, lsl #23
str T0, [XP], #+4
mov N, #5
C 5 iterations, reading limbs 18-20, 21-23, 24-26, 27-29, 30-32
C and adding to limbs 1-3, 4-6, 7-9, 19-12, 13-15
.Loop:
ldm XP, {T0,T1,T2} C 1+3*k -- 3+3*k
lsr F0, F3, #9
ldm HP!, {F1,F2,F3} C 18+3*k -- 20+3*k
orr F0, F0, F1, lsl #23
lsr F1, F1, #9
orr F1, F1, F2, lsl #23
lsr F2, F2, #9
orr F2, F2, F3, lsl #23
adcs T0, T0, F0
adcs T1, T1, F1
adcs T2, T2, F2
sub N, N, #1
stm XP!,{T0,T1,T2}
teq N, #0
bne .Loop
ldr F0, [XP], #-64 C 16
ldr F1, [HP] C 33
ldr T0, .Lc511
C Handling of high limbs
C F0 = rp[16] + carry in + F3 >> 9
adcs F0, F0, F3, lsr #9
C Copy low 9 bits to H, then shift right including carry
and H, F0, T0
mov F0, F0, rrx
lsr F0, F0, #8
C Add in F1 = rp[33], with weight 2^1056 = 2^14
adds F0, F0, F1, lsl #14
lsr F1, F1, #18
adc F1, F1, #0
ldm XP!, {T0, T1} C 0-1
adds T0, T0, F0
adcs T1, T1, F1
stm RP!, {T0, T1}
ldm XP!, {T0,T1,T2,F0,F1,F2,F3} C 2-8
adcs T0, T0, #0
adcs T1, T1, #0
adcs T2, T2, #0
adcs F0, F0, #0
adcs F1, F1, #0
adcs F2, F2, #0
adcs F3, F3, #0
stm RP!, {T0,T1,T2,F0,F1,F2,F3} C 2-8
ldm XP, {T0,T1,T2,F0,F1,F2,F3} C 9-15
adcs T0, T0, #0
adcs T1, T1, #0
adcs T2, T2, #0
adcs F0, F0, #0
adcs F1, F1, #0
adcs F2, F2, #0
adcs F3, F3, #0
adcs H, H, #0
stm RP, {T0,T1,T2,F0,F1,F2,F3,H} C 9-16
pop {r4,r5,r6,r7,r8,r10,pc}
EPILOGUE(_nettle_ecc_secp521r1_modp)
C arm/fat/aes-decrypt-internal-2.asm
ifelse(`
Copyright (C) 2015 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/.
')
define(`fat_transform', `$1_armv6')
include_src(`arm/v6/aes-decrypt-internal.asm')
C arm/fat/aes-decrypt-internal.asm
ifelse(`
Copyright (C) 2015 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/.
')
define(`fat_transform', `$1_arm')
include_src(`arm/aes-decrypt-internal.asm')
C arm/fat/aes-encrypt-internal-2.asm
ifelse(`
Copyright (C) 2015 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/.
')
define(`fat_transform', `$1_armv6')
include_src(`arm/v6/aes-encrypt-internal.asm')