/* gf128mul.c - GF(2^128) multiplication functions
*
* Copyright ( c ) 2003 , Dr Brian Gladman , Worcester , UK .
* Copyright ( c ) 2006 , Rik Snel < rsnel @ cube . dyndns . org >
*
* Based on Dr Brian Gladman ' s ( GPL ' d ) work published at
* http : //gladman.plushost.co.uk/oldsite/cryptography_technology/index.php
* See the original copyright notice below .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of 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 .
*/
/*
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright ( c ) 2003 , Dr Brian Gladman , Worcester , UK . All rights reserved .
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed ( with or without changes ) provided that :
1 . distributions of this source code include the above copyright
notice , this list of conditions and the following disclaimer ;
2 . distributions in binary form include the above copyright
notice , this list of conditions and the following disclaimer
in the documentation and / or other associated materials ;
3 . the copyright holder ' s name is not used to endorse products
built using this software without specific written permission .
ALTERNATIVELY , provided that this notice is retained in full , this product
may be distributed under the terms of the GNU General Public License ( GPL ) ,
in which case the provisions of the GPL apply INSTEAD OF those given above .
DISCLAIMER
This software is provided ' as is ' with no explicit or implied warranties
in respect of its properties , including , but not limited to , correctness
and / or fitness for purpose .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Issue 31 / 01 / 2006
This file provides fast multiplication in GF ( 2 ^ 128 ) as required by several
cryptographic authentication modes
*/
#include <crypto/gf128mul.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#define gf128mul_dat(q) { \
q(0 x00), q(0 x01), q(0 x02), q(0 x03), q(0 x04), q(0 x05), q(0 x06), q(0 x07),\
q(0 x08), q(0 x09), q(0 x0a), q(0 x0b), q(0 x0c), q(0 x0d), q(0 x0e), q(0 x0f),\
q(0 x10), q(0 x11), q(0 x12), q(0 x13), q(0 x14), q(0 x15), q(0 x16), q(0 x17),\
q(0 x18), q(0 x19), q(0 x1a), q(0 x1b), q(0 x1c), q(0 x1d), q(0 x1e), q(0 x1f),\
q(0 x20), q(0 x21), q(0 x22), q(0 x23), q(0 x24), q(0 x25), q(0 x26), q(0 x27),\
q(0 x28), q(0 x29), q(0 x2a), q(0 x2b), q(0 x2c), q(0 x2d), q(0 x2e), q(0 x2f),\
q(0 x30), q(0 x31), q(0 x32), q(0 x33), q(0 x34), q(0 x35), q(0 x36), q(0 x37),\
q(0 x38), q(0 x39), q(0 x3a), q(0 x3b), q(0 x3c), q(0 x3d), q(0 x3e), q(0 x3f),\
q(0 x40), q(0 x41), q(0 x42), q(0 x43), q(0 x44), q(0 x45), q(0 x46), q(0 x47),\
q(0 x48), q(0 x49), q(0 x4a), q(0 x4b), q(0 x4c), q(0 x4d), q(0 x4e), q(0 x4f),\
q(0 x50), q(0 x51), q(0 x52), q(0 x53), q(0 x54), q(0 x55), q(0 x56), q(0 x57),\
q(0 x58), q(0 x59), q(0 x5a), q(0 x5b), q(0 x5c), q(0 x5d), q(0 x5e), q(0 x5f),\
q(0 x60), q(0 x61), q(0 x62), q(0 x63), q(0 x64), q(0 x65), q(0 x66), q(0 x67),\
q(0 x68), q(0 x69), q(0 x6a), q(0 x6b), q(0 x6c), q(0 x6d), q(0 x6e), q(0 x6f),\
q(0 x70), q(0 x71), q(0 x72), q(0 x73), q(0 x74), q(0 x75), q(0 x76), q(0 x77),\
q(0 x78), q(0 x79), q(0 x7a), q(0 x7b), q(0 x7c), q(0 x7d), q(0 x7e), q(0 x7f),\
q(0 x80), q(0 x81), q(0 x82), q(0 x83), q(0 x84), q(0 x85), q(0 x86), q(0 x87),\
q(0 x88), q(0 x89), q(0 x8a), q(0 x8b), q(0 x8c), q(0 x8d), q(0 x8e), q(0 x8f),\
q(0 x90), q(0 x91), q(0 x92), q(0 x93), q(0 x94), q(0 x95), q(0 x96), q(0 x97),\
q(0 x98), q(0 x99), q(0 x9a), q(0 x9b), q(0 x9c), q(0 x9d), q(0 x9e), q(0 x9f),\
q(0 xa0), q(0 xa1), q(0 xa2), q(0 xa3), q(0 xa4), q(0 xa5), q(0 xa6), q(0 xa7),\
q(0 xa8), q(0 xa9), q(0 xaa), q(0 xab), q(0 xac), q(0 xad), q(0 xae), q(0 xaf),\
q(0 xb0), q(0 xb1), q(0 xb2), q(0 xb3), q(0 xb4), q(0 xb5), q(0 xb6), q(0 xb7),\
q(0 xb8), q(0 xb9), q(0 xba), q(0 xbb), q(0 xbc), q(0 xbd), q(0 xbe), q(0 xbf),\
q(0 xc0), q(0 xc1), q(0 xc2), q(0 xc3), q(0 xc4), q(0 xc5), q(0 xc6), q(0 xc7),\
q(0 xc8), q(0 xc9), q(0 xca), q(0 xcb), q(0 xcc), q(0 xcd), q(0 xce), q(0 xcf),\
q(0 xd0), q(0 xd1), q(0 xd2), q(0 xd3), q(0 xd4), q(0 xd5), q(0 xd6), q(0 xd7),\
q(0 xd8), q(0 xd9), q(0 xda), q(0 xdb), q(0 xdc), q(0 xdd), q(0 xde), q(0 xdf),\
q(0 xe0), q(0 xe1), q(0 xe2), q(0 xe3), q(0 xe4), q(0 xe5), q(0 xe6), q(0 xe7),\
q(0 xe8), q(0 xe9), q(0 xea), q(0 xeb), q(0 xec), q(0 xed), q(0 xee), q(0 xef),\
q(0 xf0), q(0 xf1), q(0 xf2), q(0 xf3), q(0 xf4), q(0 xf5), q(0 xf6), q(0 xf7),\
q(0 xf8), q(0 xf9), q(0 xfa), q(0 xfb), q(0 xfc), q(0 xfd), q(0 xfe), q(0 xff) \
}
/*
* Given a value i in 0 . . 255 as the byte overflow when a field element
* in GF ( 2 ^ 128 ) is multiplied by x ^ 8 , the following macro returns the
* 16 - bit value that must be XOR - ed into the low - degree end of the
* product to reduce it modulo the polynomial x ^ 128 + x ^ 7 + x ^ 2 + x + 1 .
*
* There are two versions of the macro , and hence two tables : one for
* the " be " convention where the highest - order bit is the coefficient of
* the highest - degree polynomial term , and one for the " le " convention
* where the highest - order bit is the coefficient of the lowest - degree
* polynomial term . In both cases the values are stored in CPU byte
* endianness such that the coefficients are ordered consistently across
* bytes , i . e . in the " be " table bits 15 . . 0 of the stored value
* correspond to the coefficients of x ^ 15 . . x ^ 0 , and in the " le " table
* bits 15 . . 0 correspond to the coefficients of x ^ 0 . . x ^ 15 .
*
* Therefore , provided that the appropriate byte endianness conversions
* are done by the multiplication functions ( and these must be in place
* anyway to support both little endian and big endian CPUs ) , the " be "
* table can be used for multiplications of both " bbe " and " ble "
* elements , and the " le " table can be used for multiplications of both
* " lle " and " lbe " elements .
*/
#define xda_be(i) ( \
(i & 0 x80 ? 0 x4380 : 0 ) ^ (i & 0 x40 ? 0 x21c0 : 0 ) ^ \
(i & 0 x20 ? 0 x10e0 : 0 ) ^ (i & 0 x10 ? 0 x0870 : 0 ) ^ \
(i & 0 x08 ? 0 x0438 : 0 ) ^ (i & 0 x04 ? 0 x021c : 0 ) ^ \
(i & 0 x02 ? 0 x010e : 0 ) ^ (i & 0 x01 ? 0 x0087 : 0 ) \
)
#define xda_le(i) ( \
(i & 0 x80 ? 0 xe100 : 0 ) ^ (i & 0 x40 ? 0 x7080 : 0 ) ^ \
(i & 0 x20 ? 0 x3840 : 0 ) ^ (i & 0 x10 ? 0 x1c20 : 0 ) ^ \
(i & 0 x08 ? 0 x0e10 : 0 ) ^ (i & 0 x04 ? 0 x0708 : 0 ) ^ \
(i & 0 x02 ? 0 x0384 : 0 ) ^ (i & 0 x01 ? 0 x01c2 : 0 ) \
)
static const u16 gf128mul_table_le[256 ] = gf128mul_dat(xda_le);
static const u16 gf128mul_table_be[256 ] = gf128mul_dat(xda_be);
/*
* The following functions multiply a field element by x ^ 8 in
* the polynomial field representation . They use 64 - bit word operations
* to gain speed but compensate for machine endianness and hence work
* correctly on both styles of machine .
*/
static void gf128mul_x8_lle(be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
u64 _tt = gf128mul_table_le[b & 0 xff];
x->b = cpu_to_be64((b >> 8 ) | (a << 56 ));
x->a = cpu_to_be64((a >> 8 ) ^ (_tt << 48 ));
}
/* time invariant version of gf128mul_x8_lle */
static void gf128mul_x8_lle_ti(be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
u64 _tt = xda_le(b & 0 xff); /* avoid table lookup */
x->b = cpu_to_be64((b >> 8 ) | (a << 56 ));
x->a = cpu_to_be64((a >> 8 ) ^ (_tt << 48 ));
}
static void gf128mul_x8_bbe(be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
u64 _tt = gf128mul_table_be[a >> 56 ];
x->a = cpu_to_be64((a << 8 ) | (b >> 56 ));
x->b = cpu_to_be64((b << 8 ) ^ _tt);
}
void gf128mul_x8_ble(le128 *r, const le128 *x)
{
u64 a = le64_to_cpu(x->a);
u64 b = le64_to_cpu(x->b);
u64 _tt = gf128mul_table_be[a >> 56 ];
r->a = cpu_to_le64((a << 8 ) | (b >> 56 ));
r->b = cpu_to_le64((b << 8 ) ^ _tt);
}
EXPORT_SYMBOL(gf128mul_x8_ble);
void gf128mul_lle(be128 *r, const be128 *b)
{
/*
* The p array should be aligned to twice the size of its element type ,
* so that every even / odd pair is guaranteed to share a cacheline
* ( assuming a cacheline size of 32 bytes or more , which is by far the
* most common ) . This ensures that each be128_xor ( ) call in the loop
* takes the same amount of time regardless of the value of ' ch ' , which
* is derived from function parameter ' b ' , which is commonly used as a
* key , e . g . , for GHASH . The odd array elements are all set to zero ,
* making each be128_xor ( ) a NOP if its associated bit in ' ch ' is not
* set , and this is equivalent to calling be128_xor ( ) conditionally .
* This approach aims to avoid leaking information about such keys
* through execution time variances .
*
* Unfortunately , _ _ aligned ( 16 ) or higher does not work on x86 for
* variables on the stack so we need to perform the alignment by hand .
*/
be128 array[16 + 3 ] = {};
be128 *p = PTR_ALIGN(&array[0 ], 2 * sizeof (be128));
int i;
p[0 ] = *r;
for (i = 0 ; i < 7 ; ++i)
gf128mul_x_lle(&p[2 * i + 2 ], &p[2 * i]);
memset(r, 0 , sizeof (*r));
for (i = 0 ;;) {
u8 ch = ((u8 *)b)[15 - i];
be128_xor(r, r, &p[ 0 + !(ch & 0 x80)]);
be128_xor(r, r, &p[ 2 + !(ch & 0 x40)]);
be128_xor(r, r, &p[ 4 + !(ch & 0 x20)]);
be128_xor(r, r, &p[ 6 + !(ch & 0 x10)]);
be128_xor(r, r, &p[ 8 + !(ch & 0 x08)]);
be128_xor(r, r, &p[10 + !(ch & 0 x04)]);
be128_xor(r, r, &p[12 + !(ch & 0 x02)]);
be128_xor(r, r, &p[14 + !(ch & 0 x01)]);
if (++i >= 16 )
break ;
gf128mul_x8_lle_ti(r); /* use the time invariant version */
}
}
EXPORT_SYMBOL(gf128mul_lle);
/* This version uses 64k bytes of table space.
A 16 byte buffer has to be multiplied by a 16 byte key
value in GF ( 2 ^ 128 ) . If we consider a GF ( 2 ^ 128 ) value in
the buffer ' s lowest byte , we can construct a table of
the 256 16 byte values that result from the 256 values
of this byte . This requires 4096 bytes . But we also
need tables for each of the 16 higher bytes in the
buffer as well , which makes 64 kbytes in total .
*/
/* additional explanation
* t [ 0 ] [ BYTE ] contains g * BYTE
* t [ 1 ] [ BYTE ] contains g * x ^ 8 * BYTE
* . .
* t[15][BYTE] contains g*x^120*BYTE */
struct gf128mul_64k *gf128mul_init_64k_bbe(const be128 *g)
{
struct gf128mul_64k *t;
int i, j, k;
t = kzalloc(sizeof (*t), GFP_KERNEL);
if (!t)
goto out;
for (i = 0 ; i < 16 ; i++) {
t->t[i] = kzalloc(sizeof (*t->t[i]), GFP_KERNEL);
if (!t->t[i]) {
gf128mul_free_64k(t);
t = NULL;
goto out;
}
}
t->t[0 ]->t[1 ] = *g;
for (j = 1 ; j <= 64 ; j <<= 1 )
gf128mul_x_bbe(&t->t[0 ]->t[j + j], &t->t[0 ]->t[j]);
for (i = 0 ;;) {
for (j = 2 ; j < 256 ; j += j)
for (k = 1 ; k < j; ++k)
be128_xor(&t->t[i]->t[j + k],
&t->t[i]->t[j], &t->t[i]->t[k]);
if (++i >= 16 )
break ;
for (j = 128 ; j > 0 ; j >>= 1 ) {
t->t[i]->t[j] = t->t[i - 1 ]->t[j];
gf128mul_x8_bbe(&t->t[i]->t[j]);
}
}
out:
return t;
}
EXPORT_SYMBOL(gf128mul_init_64k_bbe);
void gf128mul_free_64k(struct gf128mul_64k *t)
{
int i;
for (i = 0 ; i < 16 ; i++)
kfree_sensitive(t->t[i]);
kfree_sensitive(t);
}
EXPORT_SYMBOL(gf128mul_free_64k);
void gf128mul_64k_bbe(be128 *a, const struct gf128mul_64k *t)
{
u8 *ap = (u8 *)a;
be128 r[1 ];
int i;
*r = t->t[0 ]->t[ap[15 ]];
for (i = 1 ; i < 16 ; ++i)
be128_xor(r, r, &t->t[i]->t[ap[15 - i]]);
*a = *r;
}
EXPORT_SYMBOL(gf128mul_64k_bbe);
/* This version uses 4k bytes of table space.
A 16 byte buffer has to be multiplied by a 16 byte key
value in GF ( 2 ^ 128 ) . If we consider a GF ( 2 ^ 128 ) value in a
single byte , we can construct a table of the 256 16 byte
values that result from the 256 values of this byte .
This requires 4096 bytes . If we take the highest byte in
the buffer and use this table to get the result , we then
have to multiply by x ^ 120 to get the final value . For the
next highest byte the result has to be multiplied by x ^ 112
and so on . But we can do this by accumulating the result
in an accumulator starting with the result for the top
byte . We repeatedly multiply the accumulator value by
x ^ 8 and then add in ( i . e . xor ) the 16 bytes of the next
lower byte in the buffer , stopping when we reach the
lowest byte . This requires a 4096 byte table .
*/
struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g)
{
struct gf128mul_4k *t;
int j, k;
t = kzalloc(sizeof (*t), GFP_KERNEL);
if (!t)
goto out;
t->t[128 ] = *g;
for (j = 64 ; j > 0 ; j >>= 1 )
gf128mul_x_lle(&t->t[j], &t->t[j+j]);
for (j = 2 ; j < 256 ; j += j)
for (k = 1 ; k < j; ++k)
be128_xor(&t->t[j + k], &t->t[j], &t->t[k]);
out:
return t;
}
EXPORT_SYMBOL(gf128mul_init_4k_lle);
void gf128mul_4k_lle(be128 *a, const struct gf128mul_4k *t)
{
u8 *ap = (u8 *)a;
be128 r[1 ];
int i = 15 ;
*r = t->t[ap[15 ]];
while (i--) {
gf128mul_x8_lle(r);
be128_xor(r, r, &t->t[ap[i]]);
}
*a = *r;
}
EXPORT_SYMBOL(gf128mul_4k_lle);
MODULE_LICENSE("GPL" );
MODULE_DESCRIPTION("Functions for multiplying elements of GF(2^128)" );
Messung V0.5 in Prozent C=97 H=48 G=76
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland