1 /* 2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the License); you may 5 * not use this file except in compliance with the License. 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 */ 9 10 11 #ifndef GMSSL_SM4_H 12 #define GMSSL_SM4_H 13 14 #include <stdint.h> 15 #include <string.h> 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 22 /* 23 SM4 Public API 24 25 SM4_KEY_SIZE 26 SM4_BLOCK_SIZE 27 28 SM4_CBC_CTX 29 sm4_cbc_encrypt_init 30 sm4_cbc_encrypt_update 31 sm4_cbc_encrypt_finish 32 sm4_cbc_decrypt_init 33 sm4_cbc_decrypt_update 34 sm4_cbc_decrypt_finish 35 36 SM4_CTR_CTX 37 sm4_ctr_encrypt_init 38 sm4_ctr_encrypt_update 39 sm4_ctr_encrypt_finish 40 sm4_ctr_decrypt_init 41 sm4_ctr_decrypt_update 42 sm4_ctr_decrypt_finish 43 */ 44 45 #define SM4_KEY_SIZE (16) 46 #define SM4_BLOCK_SIZE (16) 47 #define SM4_NUM_ROUNDS (32) 48 49 50 typedef struct { 51 uint32_t rk[SM4_NUM_ROUNDS]; 52 } SM4_KEY; 53 54 void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); 55 void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); 56 void sm4_encrypt(const SM4_KEY *key, const uint8_t in[SM4_BLOCK_SIZE], uint8_t out[SM4_BLOCK_SIZE]); 57 #define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out) 58 59 60 void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], 61 const uint8_t *in, size_t nblocks, uint8_t *out); 62 void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], 63 const uint8_t *in, size_t nblocks, uint8_t *out); 64 int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], 65 const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); 66 int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[SM4_BLOCK_SIZE], 67 const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); 68 69 70 void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE], 71 const uint8_t *in, size_t inlen, uint8_t *out); 72 #define sm4_ctr_decrypt(key,ctr,in,inlen,out) sm4_ctr_encrypt(key,ctr,in,inlen,out) 73 74 75 #define SM4_GCM_IV_MIN_SIZE 1 76 #define SM4_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3))) 77 #define SM4_GCM_IV_DEFAULT_BITS 96 78 #define SM4_GCM_IV_DEFAULT_SIZE 12 79 80 #define SM4_GCM_MIN_AAD_SIZE 0 81 #define SM4_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3))) 82 83 #define SM4_GCM_MIN_PLAINTEXT_SIZE 0 84 #define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) 85 86 #define SM4_GCM_MAX_TAG_SIZE 16 87 88 int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, 89 const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, 90 uint8_t *out, size_t taglen, uint8_t *tag); 91 int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen, 92 const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, 93 const uint8_t *tag, size_t taglen, uint8_t *out); 94 95 96 typedef struct { 97 SM4_KEY sm4_key; 98 uint8_t iv[SM4_BLOCK_SIZE]; 99 uint8_t block[SM4_BLOCK_SIZE]; 100 size_t block_nbytes; 101 } SM4_CBC_CTX; 102 103 int sm4_cbc_encrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]); 104 int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); 105 int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen); 106 107 int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t iv[SM4_BLOCK_SIZE]); 108 int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); 109 int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen); 110 111 112 typedef struct { 113 SM4_KEY sm4_key; 114 uint8_t ctr[SM4_BLOCK_SIZE]; 115 uint8_t block[SM4_BLOCK_SIZE]; 116 size_t block_nbytes; 117 } SM4_CTR_CTX; 118 119 int sm4_ctr_encrypt_init(SM4_CTR_CTX *ctx, const uint8_t key[SM4_KEY_SIZE], const uint8_t ctr[SM4_BLOCK_SIZE]); 120 int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); 121 int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen); 122 123 #define sm4_ctr_decrypt_init(ctx,key,ctr) sm4_ctr_encrypt_init(ctx,key,ctr) 124 #define sm4_ctr_decrypt_update(ctx,in,inlen,out,outlen) sm4_ctr_encrypt_update(ctx,in,inlen,out,outlen) 125 #define sm4_ctr_decrypt_finish(ctx,out,outlen) sm4_ctr_encrypt_finish(ctx,out,outlen) 126 127 128 #ifdef __cplusplus 129 } 130 #endif 131 #endif 132