mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-13 20:06:24 +08:00
add CBC-MAC and GM OTP, not tested
This commit is contained in:
80
crypto/sm3/hmac_sm3.c
Normal file
80
crypto/sm3/hmac_sm3.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "hmac_sm3.h"
|
||||
|
||||
/**
|
||||
* HMAC_k(m) = H((k ^ opad), H((k ^ ipad), m))
|
||||
* pseudo-code:
|
||||
* function hmac(key, message)
|
||||
* opad = [0x5c * blocksize]
|
||||
* ipad = [0x36 * blocksize]
|
||||
* if (length(key) > blocksize) then
|
||||
* key = hash(key)
|
||||
* end if
|
||||
* for i from 0 to length(key) - 1 step 1
|
||||
* ipad[i] = ipad[i] XOR key[i]
|
||||
* opad[i] = opad[i] XOR key[i]
|
||||
* end for
|
||||
* return hash(opad || hash(ipad || message))
|
||||
* end function
|
||||
*/
|
||||
|
||||
|
||||
#define IPAD 0x36
|
||||
#define OPAD 0x5C
|
||||
|
||||
|
||||
|
||||
void hmac_sm3_init(hmac_sm3_ctx_t *ctx, const unsigned char *key, size_t key_len)
|
||||
{
|
||||
int i;
|
||||
unsigned char ipad[SM3_DIGEST_LENGTH];
|
||||
|
||||
if (key_len <= SM3_BLOCK_SIZE) {
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->key + key_len, 0, SM3_BLOCK_SIZE - key_len);
|
||||
} else {
|
||||
sm3_init(&ctx->sm3_ctx);
|
||||
sm3_update(&ctx->sm3_ctx, key, key_len);
|
||||
sm3_final(&ctx->sm3_ctx, ctx->key);
|
||||
memset(ctx->key + SM3_DIGEST_LENGTH, 0,
|
||||
SM3_BLOCK_SIZE - SM3_DIGEST_LENGTH);
|
||||
}
|
||||
for (i = 0; i < SM3_BLOCK_SIZE; i++) {
|
||||
ctx->key[i] ^= IPAD;
|
||||
}
|
||||
|
||||
sm3_init(&ctx->sm3_ctx);
|
||||
sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void hmac_sm3_update(hmac_sm3_ctx_t *ctx, const unsigned char *data, size_t data_len)
|
||||
{
|
||||
sm3_update(&ctx->sm3_ctx, data, data_len);
|
||||
}
|
||||
|
||||
void hmac_sm3_final(hmac_sm3_ctx_t *ctx, unsigned char mac[HMAC_SM3_MAC_SIZE])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SM3_BLOCK_SIZE; i++) {
|
||||
ctx->key[i] ^= (IPAD ^ OPAD);
|
||||
}
|
||||
sm3_final(&ctx->sm3_ctx, mac);
|
||||
sm3_init(&ctx->sm3_ctx);
|
||||
sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE);
|
||||
sm3_update(&ctx->sm3_ctx, mac, SM3_DIGEST_LENGTH);
|
||||
sm3_final(&ctx->sm3_ctx, mac);
|
||||
}
|
||||
|
||||
void hmac_sm3(const unsigned char *data, size_t data_len,
|
||||
const unsigned char *key, size_t key_len, unsigned char mac[HMAC_SM3_MAC_SIZE])
|
||||
{
|
||||
hmac_sm3_ctx_t ctx;
|
||||
|
||||
hmac_sm3_init(&ctx, key, key_len);
|
||||
hmac_sm3_update(&ctx, data, data_len);
|
||||
hmac_sm3_final(&ctx, mac);
|
||||
|
||||
memset(&ctx, 0, sizeof(hmac_sm3_ctx_t));
|
||||
}
|
||||
|
||||
29
crypto/sm3/hmac_sm3.h
Normal file
29
crypto/sm3/hmac_sm3.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef LIBSM3_HMAC_SM3_H
|
||||
#define LIBSM3_HMAC_SM3_H
|
||||
|
||||
#include "sm3.h"
|
||||
|
||||
#define HMAC_SM3_MAC_SIZE SM3_DIGEST_LENGTH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
sm3_ctx_t sm3_ctx;
|
||||
unsigned char key[SM3_DIGEST_LENGTH];
|
||||
} hmac_sm3_ctx_t;
|
||||
|
||||
|
||||
void hmac_sm3_init(hmac_sm3_ctx_t *ctx, const unsigned char *key, size_t key_len);
|
||||
void hmac_sm3_update(hmac_sm3_ctx_t *ctx, const unsigned char *data, size_t data_len);
|
||||
void hmac_sm3_final(hmac_sm3_ctx_t *ctx, unsigned char mac[HMAC_SM3_MAC_SIZE]);
|
||||
void hmac_sm3(const unsigned char *data, size_t data_len,
|
||||
const unsigned char *key, size_t key_len, unsigned char mac[HMAC_SM3_MAC_SIZE]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
68
crypto/sm3/hmac_sm3_test.c
Normal file
68
crypto/sm3/hmac_sm3_test.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "hmac_sm3.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int hmac_sm3_test()
|
||||
{
|
||||
int ret = 0;
|
||||
int i, j;
|
||||
unsigned char mac[HMAC_SM3_MAC_SIZE];
|
||||
hmac_sm3_ctx_t ctx;
|
||||
|
||||
char *testarray[4] = {
|
||||
"abc",
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"a",
|
||||
"01234567012345670123456701234567"
|
||||
};
|
||||
int repeatcount[4] = { 1, 1, 1000000, 20 };
|
||||
unsigned char key[4] = {
|
||||
"hello",
|
||||
"world",
|
||||
"23492304982304982340923480",
|
||||
"a"
|
||||
};
|
||||
unsigned char result[4][32] = {
|
||||
{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0},
|
||||
{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0},
|
||||
{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0},
|
||||
{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0},
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(testarray)/sizeof(testarray[0]); i++) {
|
||||
hmac_sm3_init(&ctx, key[i], key_length[i]);
|
||||
for (j = 0; j < repeatcount[i]; j++) {
|
||||
hmac_sm3_update(&ctx, (const unsigned char *)testarray[i],
|
||||
strlen(testarray[i]));
|
||||
}
|
||||
hmac_sm3_final(&ctx, mac);
|
||||
if (memcmp(mac, &result[i][0], sizeof(mac)) != 0) {
|
||||
fprintf(stderr, "hmac-sm3 test-%d failed\n", i);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
printf("hmac-sm3 test success!\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return hmac_sm3_test();
|
||||
}
|
||||
|
||||
46
crypto/sm3/sm3dgst.c
Normal file
46
crypto/sm3/sm3dgst.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include "sm3.h"
|
||||
|
||||
/*
|
||||
* usage of sm3dgst:
|
||||
* ./sm3dgst <file>
|
||||
* 324234234234235234234234234234
|
||||
*
|
||||
* echo "hello world" | sm3dgst
|
||||
* lksjdlfksdjlfkjsdlfkjsdlfkjsdljkfffffffldjfk=
|
||||
*
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
sm3_ctx_t ctx;
|
||||
unsigned char dgst[SM3_DIGEST_LENGTH];
|
||||
unsigned char buf[4096];
|
||||
ssize_t len;
|
||||
int i;
|
||||
|
||||
if (argc > 1) {
|
||||
printf("usage: %s < file\n", basename(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sm3_init(&ctx);
|
||||
|
||||
while ((len = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
|
||||
sm3_update(&ctx, buf, len);
|
||||
}
|
||||
memset(dgst, 0, sizeof(dgst));
|
||||
sm3_final(&ctx, dgst);
|
||||
|
||||
for (i = 0; i < sizeof(dgst); i++) {
|
||||
printf("%02x", dgst[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
94
crypto/sm3/sm3test2.c
Normal file
94
crypto/sm3/sm3test2.c
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sm3.h"
|
||||
|
||||
int sm3_test1()
|
||||
{
|
||||
char *msg = "abc";
|
||||
unsigned char dgst[SM3_DIGEST_LENGTH];
|
||||
unsigned char result[] = {
|
||||
0x66,0xc7,0xf0,0xf4,0x62,0xee,0xed,0xd9,
|
||||
0xd1,0xf2,0xd4,0x6b,0xdc,0x10,0xe4,0xe2,
|
||||
0x41,0x67,0xc4,0x87,0x5c,0xf2,0xf7,0xa2,
|
||||
0x29,0x7d,0xa0,0x2b,0x8f,0x4b,0xa8,0xe0
|
||||
};
|
||||
int i;
|
||||
|
||||
printf("sm3 test 1\n");
|
||||
memset(dgst, 0, sizeof(dgst));
|
||||
sm3((unsigned char *)msg, strlen(msg), dgst);
|
||||
|
||||
printf(" message : %s\n", msg);
|
||||
printf(" digest : 0x");
|
||||
for(i = 0; i < sizeof(dgst); i++) {
|
||||
printf("%02x", dgst[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" result : ");
|
||||
if (memcmp(dgst, result, sizeof(result))) {
|
||||
printf("failed\n");
|
||||
return -1;
|
||||
} else {
|
||||
printf("passed\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sm3_test2()
|
||||
{
|
||||
unsigned char msg[] = {
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,
|
||||
};
|
||||
|
||||
unsigned char dgst[SM3_DIGEST_LENGTH];
|
||||
unsigned char result[] = {
|
||||
0xde,0xbe,0x9f,0xf9,0x22,0x75,0xb8,0xa1,
|
||||
0x38,0x60,0x48,0x89,0xc1,0x8e,0x5a,0x4d,
|
||||
0x6f,0xdb,0x70,0xe5,0x38,0x7e,0x57,0x65,
|
||||
0x29,0x3d,0xcb,0xa3,0x9c,0x0c,0x57,0x32,
|
||||
};
|
||||
int i;
|
||||
|
||||
printf("sm3 test 2\n");
|
||||
memset(dgst, 0, sizeof(dgst));
|
||||
sm3(msg, sizeof(msg), dgst);
|
||||
|
||||
printf(" message : 0x");
|
||||
for (i = 0; i < sizeof(msg); i++) {
|
||||
printf("%02x", msg[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf(" digest: 0x");
|
||||
for (i = 0; i < sizeof(dgst); i++) {
|
||||
printf("%02x", dgst[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" result : ");
|
||||
if (memcmp(dgst, result, sizeof(result))) {
|
||||
printf("failed\n");
|
||||
return -1;
|
||||
} else {
|
||||
printf("passed\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (sm3_test1())
|
||||
return -1;
|
||||
|
||||
if (sm3_test2())
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user