mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-09 15:33:58 +08:00
jni api
This commit is contained in:
@@ -22,8 +22,8 @@ TEST=sm3test.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC=sm3.c
|
||||
LIBOBJ=sm3.o
|
||||
LIBSRC=sm3.c sm3_hmac.c
|
||||
LIBOBJ=sm3.o sm3_hmac.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
@@ -66,6 +66,8 @@ tests:
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
update: depend
|
||||
|
||||
depend:
|
||||
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
|
||||
@@ -79,4 +81,5 @@ clean:
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
sm3.o: ../byteorder.h sm3.c sm3.h
|
||||
sm3.o: ../../include/openssl/sm3.h ../byteorder.h sm3.c
|
||||
sm3_hmac.o: ../../include/openssl/sm3.h sm3_hmac.c
|
||||
|
||||
66
crypto/sm3/README.md
Normal file
66
crypto/sm3/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
## SM3 Sub-library of GMSSL
|
||||
|
||||
SM3 Cryptographic Hash Algorithm is a chinese national cryptographic hash
|
||||
algorithm standard published by the State Cryptography Administration Office
|
||||
of Security Commercial Code Administration (OSCCA) of China in December 2010.
|
||||
A draft of this algorithm can be found at
|
||||
|
||||
[http://tools.ietf.org/html/draft-shen-sm3-hash-00](http://tools.ietf.org/html/draft-shen-sm3-hash-00 "RFC Draft")
|
||||
|
||||
|
||||
The SM3 take input messages as 512 bits blocks and generates
|
||||
256 bits digest values, same as SHA-256.
|
||||
|
||||
The `SM3` sub-library of GmSSL provides the implementation of SM3 hash
|
||||
algorithm, with init/update/final style of interfaces. There is also a
|
||||
demo program in `demo/gmssl/sm3.c` on how to implement a command line
|
||||
tool with the the inner API of SM3 sub-library.
|
||||
|
||||
### Usage
|
||||
|
||||
The SM3 sub-library provides the following C API:
|
||||
|
||||
```
|
||||
void sm3_init(sm3_ctx_t *ctx);
|
||||
void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len);
|
||||
void sm3_final(sm3_ctx_t *ctx, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
void sm3_compress(uint32_t digest[8], const unsigned char block[SM3_BLOCK_SIZE]);
|
||||
void sm3(const unsigned char *data, size_t datalen, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
|
||||
void sm3_hmac_init(sm3_hmac_ctx_t *ctx, const unsigned char *key, size_t key_len);
|
||||
void sm3_hmac_update(sm3_hmac_ctx_t *ctx, const unsigned char *data, size_t data_len);
|
||||
void sm3_hmac_final(sm3_hmac_ctx_t *ctx, unsigned char mac[sm3_hmac_MAC_SIZE]);
|
||||
void sm3_hmac(const unsigned char *data, size_t data_len,
|
||||
const unsigned char *key, size_t key_len, unsigned char mac[sm3_hmac_MAC_SIZE]);
|
||||
```
|
||||
|
||||
Example on using C API to digest a message:
|
||||
|
||||
```
|
||||
unsigend char buffer[SM3_DIGEST_LENGTH];
|
||||
sm3("hello", strlen("hello"), buffer);
|
||||
```
|
||||
|
||||
Example on using C API to digest a stream:
|
||||
|
||||
```
|
||||
unsigned char dgst[SM3_DIGEST_LENGTH];
|
||||
sm3_ctx_t ctx;
|
||||
sm3_init(&ctx);
|
||||
sm3_update(&ctx, "hello", strlen("hello"));
|
||||
sm3_update(&ctx, "world", strlen("world"));
|
||||
sm3_final(&ctx, dgst);
|
||||
```
|
||||
|
||||
Example on using C API to generate a HMAC tag:
|
||||
|
||||
```
|
||||
unsigned char mac[sm3_hmac_MAC_SIZE];
|
||||
sm3_hmac_ctx_t ctx;
|
||||
unsigned char key[16];
|
||||
sm3_hmac_init(&ctx, key, sizeof(key));
|
||||
sm3_hmac_update(&ctx, "hello", strlen("hello"));
|
||||
sm3_hmac_update(&ctx, "world", strlen("world"));
|
||||
sm3_hmac_final(&ctx, mac);
|
||||
```
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#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));
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
#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();
|
||||
}
|
||||
|
||||
@@ -49,13 +49,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "sm3.h"
|
||||
#include "../byteorder.h"
|
||||
#include <string.h>
|
||||
#include "../byteorder.h"
|
||||
#include <openssl/sm3.h>
|
||||
|
||||
|
||||
int sm3_init(sm3_ctx_t *ctx)
|
||||
void sm3_init(sm3_ctx_t *ctx)
|
||||
{
|
||||
ctx->digest[0] = 0x7380166F;
|
||||
ctx->digest[1] = 0x4914B2B9;
|
||||
@@ -65,22 +63,19 @@ int sm3_init(sm3_ctx_t *ctx)
|
||||
ctx->digest[5] = 0x163138AA;
|
||||
ctx->digest[6] = 0xE38DEE4D;
|
||||
ctx->digest[7] = 0xB0FB0E4E;
|
||||
|
||||
|
||||
ctx->nblocks = 0;
|
||||
ctx->num = 0;
|
||||
if(ctx == NULL) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len)
|
||||
void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len)
|
||||
{
|
||||
if(ctx == NULL) return 0;
|
||||
if (ctx->num) {
|
||||
unsigned int left = SM3_BLOCK_SIZE - ctx->num;
|
||||
if (data_len < left) {
|
||||
memcpy(ctx->block + ctx->num, data, data_len);
|
||||
ctx->num += data_len;
|
||||
return 1;
|
||||
return;
|
||||
} else {
|
||||
memcpy(ctx->block + ctx->num, data, left);
|
||||
sm3_compress(ctx->digest, ctx->block);
|
||||
@@ -99,18 +94,16 @@ int sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len)
|
||||
if (data_len) {
|
||||
memcpy(ctx->block, data, data_len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm3_final(sm3_ctx_t *ctx, unsigned char *digest)
|
||||
void sm3_final(sm3_ctx_t *ctx, unsigned char *digest)
|
||||
{
|
||||
if(ctx == NULL) return 0;
|
||||
int i;
|
||||
uint32_t *pdigest = (uint32_t *)digest;
|
||||
uint32_t *count = (uint32_t *)(ctx->block + SM3_BLOCK_SIZE - 8);
|
||||
|
||||
|
||||
ctx->block[ctx->num] = 0x80;
|
||||
|
||||
|
||||
if (ctx->num + 9 <= SM3_BLOCK_SIZE) {
|
||||
memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9);
|
||||
} else {
|
||||
@@ -121,23 +114,22 @@ int sm3_final(sm3_ctx_t *ctx, unsigned char *digest)
|
||||
|
||||
count[0] = cpu_to_be32((ctx->nblocks) >> 23);
|
||||
count[1] = cpu_to_be32((ctx->nblocks << 9) + (ctx->num << 3));
|
||||
|
||||
|
||||
sm3_compress(ctx->digest, ctx->block);
|
||||
for (i = 0; i < sizeof(ctx->digest)/sizeof(ctx->digest[0]); i++) {
|
||||
pdigest[i] = cpu_to_be32(ctx->digest[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define ROTATELEFT(X,n) (((X)<<(n)) | ((X)>>(32-(n))))
|
||||
|
||||
#define P0(x) ((x) ^ ROTATELEFT((x),9) ^ ROTATELEFT((x),17))
|
||||
#define P1(x) ((x) ^ ROTATELEFT((x),15) ^ ROTATELEFT((x),23))
|
||||
#define P0(x) ((x) ^ ROTATELEFT((x),9) ^ ROTATELEFT((x),17))
|
||||
#define P1(x) ((x) ^ ROTATELEFT((x),15) ^ ROTATELEFT((x),23))
|
||||
|
||||
#define FF0(x,y,z) ( (x) ^ (y) ^ (z))
|
||||
#define FF0(x,y,z) ( (x) ^ (y) ^ (z))
|
||||
#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))
|
||||
|
||||
#define GG0(x,y,z) ( (x) ^ (y) ^ (z))
|
||||
#define GG0(x,y,z) ( (x) ^ (y) ^ (z))
|
||||
#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )
|
||||
|
||||
|
||||
@@ -146,7 +138,7 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
||||
int j;
|
||||
uint32_t W[68], W1[64];
|
||||
const uint32_t *pblock = (const uint32_t *)block;
|
||||
|
||||
|
||||
uint32_t A = digest[0];
|
||||
uint32_t B = digest[1];
|
||||
uint32_t C = digest[2];
|
||||
@@ -170,7 +162,7 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
||||
for(j =0; j < 16; j++) {
|
||||
|
||||
T[j] = 0x79CC4519;
|
||||
SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7);
|
||||
SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7);
|
||||
SS2 = SS1 ^ ROTATELEFT(A,12);
|
||||
TT1 = FF0(A,B,C) + D + SS2 + W1[j];
|
||||
TT2 = GG0(E,F,G) + H + SS1 + W[j];
|
||||
@@ -187,7 +179,7 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
||||
for(j =16; j < 64; j++) {
|
||||
|
||||
T[j] = 0x7A879D8A;
|
||||
SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7);
|
||||
SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7);
|
||||
SS2 = SS1 ^ ROTATELEFT(A,12);
|
||||
TT1 = FF1(A,B,C) + D + SS2 + W1[j];
|
||||
TT2 = GG1(E,F,G) + H + SS1 + W[j];
|
||||
@@ -211,7 +203,8 @@ void sm3_compress(uint32_t digest[8], const unsigned char block[64])
|
||||
digest[7] ^= H;
|
||||
}
|
||||
|
||||
void sm3(const unsigned char *msg, size_t msglen, unsigned char dgst[SM3_DIGEST_LENGTH])
|
||||
void sm3(const unsigned char *msg, size_t msglen,
|
||||
unsigned char dgst[SM3_DIGEST_LENGTH])
|
||||
{
|
||||
sm3_ctx_t ctx;
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
#define SM3_DIGEST_LENGTH 32
|
||||
#define SM3_BLOCK_SIZE 64
|
||||
#define SM3_HMAC_SIZE (SM3_DIGEST_LENGTH)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
@@ -71,11 +72,24 @@ typedef struct {
|
||||
int num;
|
||||
} sm3_ctx_t;
|
||||
|
||||
int sm3_init(sm3_ctx_t *ctx);
|
||||
int sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len);
|
||||
int sm3_final(sm3_ctx_t *ctx, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
void sm3_init(sm3_ctx_t *ctx);
|
||||
void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len);
|
||||
void sm3_final(sm3_ctx_t *ctx, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
void sm3_compress(uint32_t digest[8], const unsigned char block[SM3_BLOCK_SIZE]);
|
||||
void sm3(const unsigned char *data, size_t datalen, unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
void sm3(const unsigned char *data, size_t datalen,
|
||||
unsigned char digest[SM3_DIGEST_LENGTH]);
|
||||
|
||||
|
||||
typedef struct {
|
||||
sm3_ctx_t sm3_ctx;
|
||||
unsigned char key[SM3_DIGEST_LENGTH];
|
||||
} sm3_hmac_ctx_t;
|
||||
|
||||
void sm3_hmac_init(sm3_hmac_ctx_t *ctx, const unsigned char *key, size_t key_len);
|
||||
void sm3_hmac_update(sm3_hmac_ctx_t *ctx, const unsigned char *data, size_t data_len);
|
||||
void sm3_hmac_final(sm3_hmac_ctx_t *ctx, unsigned char mac[SM3_HMAC_SIZE]);
|
||||
void sm3_hmac(const unsigned char *data, size_t data_len,
|
||||
const unsigned char *key, size_t key_len, unsigned char mac[SM3_HMAC_SIZE]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
129
crypto/sm3/sm3_hmac.c
Normal file
129
crypto/sm3/sm3_hmac.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* crypto/sm3/sm3_hmac.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2015 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <strings.h>
|
||||
#include <openssl/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 sm3_hmac_init(sm3_hmac_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 sm3_hmac_update(sm3_hmac_ctx_t *ctx,
|
||||
const unsigned char *data, size_t data_len)
|
||||
{
|
||||
sm3_update(&ctx->sm3_ctx, data, data_len);
|
||||
}
|
||||
|
||||
void sm3_hmac_final(sm3_hmac_ctx_t *ctx, unsigned char mac[SM3_HMAC_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 sm3_hmac(const unsigned char *data, size_t data_len,
|
||||
const unsigned char *key, size_t key_len,
|
||||
unsigned char mac[SM3_HMAC_SIZE])
|
||||
{
|
||||
sm3_hmac_ctx_t ctx;
|
||||
sm3_hmac_init(&ctx, key, key_len);
|
||||
sm3_hmac_update(&ctx, data, data_len);
|
||||
sm3_hmac_final(&ctx, mac);
|
||||
bzero(&ctx, sizeof(ctx));
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -120,26 +120,4 @@ static char *pt(unsigned char *md)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -82,6 +82,65 @@ int sm3_test2()
|
||||
return 0;
|
||||
}
|
||||
|
||||
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(int argc, char *argv[])
|
||||
{
|
||||
if (sm3_test1())
|
||||
|
||||
Reference in New Issue
Block a user