// SPDX-License-Identifier: GPL-2.0-only
/*
* SHA-1 message digest algorithm
*
* Copyright 2025 Google LLC
*/
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/unaligned.h>
#include <string.h>
#include "sha1.h"
#define SHA1_BLOCK_SIZE 64
static const u32 sha1_K[4 ] = { 0 x5A827999, 0 x6ED9EBA1, 0 x8F1BBCDC, 0 xCA62C1D6 };
#define SHA1_ROUND(i, a, b, c, d, e) \
do { \
if ((i) >= 16 ) \
w[i] = rol32(w[(i) - 16 ] ^ w[(i) - 14 ] ^ w[(i) - 8 ] ^ \
w[(i) - 3 ], \
1 ); \
e += w[i] + rol32(a, 5 ) + sha1_K[(i) / 20 ]; \
if ((i) < 20 ) \
e += (b & (c ^ d)) ^ d; \
else if ((i) < 40 || (i) >= 60 ) \
e += b ^ c ^ d; \
else \
e += (c & d) ^ (b & (c ^ d)); \
b = rol32(b, 30 ); \
/* The new (a, b, c, d, e) is the old (e, a, b, c, d). */ \
} while (0 )
#define SHA1_5ROUNDS(i) \
do { \
SHA1_ROUND((i) + 0 , a, b, c, d, e); \
SHA1_ROUND((i) + 1 , e, a, b, c, d); \
SHA1_ROUND((i) + 2 , d, e, a, b, c); \
SHA1_ROUND((i) + 3 , c, d, e, a, b); \
SHA1_ROUND((i) + 4 , b, c, d, e, a); \
} while (0 )
#define SHA1_20ROUNDS(i) \
do { \
SHA1_5ROUNDS((i) + 0 ); \
SHA1_5ROUNDS((i) + 5 ); \
SHA1_5ROUNDS((i) + 10 ); \
SHA1_5ROUNDS((i) + 15 ); \
} while (0 )
static void sha1_blocks(u32 h[5 ], const u8 *data, size_t nblocks)
{
while (nblocks--) {
u32 a = h[0 ];
u32 b = h[1 ];
u32 c = h[2 ];
u32 d = h[3 ];
u32 e = h[4 ];
u32 w[80 ];
for (int i = 0 ; i < 16 ; i++)
w[i] = get_unaligned_be32(&data[i * 4 ]);
SHA1_20ROUNDS(0 );
SHA1_20ROUNDS(20 );
SHA1_20ROUNDS(40 );
SHA1_20ROUNDS(60 );
h[0 ] += a;
h[1 ] += b;
h[2 ] += c;
h[3 ] += d;
h[4 ] += e;
data += SHA1_BLOCK_SIZE;
}
}
/* Calculate the SHA-1 message digest of the given data. */
void sha1(const void *data, size_t len, u8 out[SHA1_DIGEST_SIZE])
{
u32 h[5 ] = { 0 x67452301, 0 xEFCDAB89, 0 x98BADCFE, 0 x10325476,
0 xC3D2E1F0 };
u8 final_data[2 * SHA1_BLOCK_SIZE] = { 0 };
size_t final_len = len % SHA1_BLOCK_SIZE;
sha1_blocks(h, data, len / SHA1_BLOCK_SIZE);
memcpy(final_data, data + len - final_len, final_len);
final_data[final_len] = 0 x80;
final_len = round_up(final_len + 9 , SHA1_BLOCK_SIZE);
put_unaligned_be64((u64)len * 8 , &final_data[final_len - 8 ]);
sha1_blocks(h, final_data, final_len / SHA1_BLOCK_SIZE);
for (int i = 0 ; i < 5 ; i++)
put_unaligned_be32(h[i], &out[i * 4 ]);
}
Messung V0.5 in Prozent C=95 H=93 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-08)
¤
*© Formatika GbR, Deutschland