1 /* $OpenBSD: sm2crypttest.c,v 1.1.1.1 2021/08/18 16:06:56 tb Exp $ */ 2 /* 3 * Copyright (c) 2017, 2019 Ribose Inc 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <openssl/bio.h> 23 #include <openssl/evp.h> 24 #include <openssl/bn.h> 25 #include <openssl/crypto.h> 26 #include <openssl/err.h> 27 #include <openssl/rand.h> 28 29 #ifdef OPENSSL_NO_SM2 30 int main(int argc, char *argv[]) 31 { 32 printf("No SM2 support\n"); 33 return (0); 34 } 35 #else 36 #include <openssl/sm2.h> 37 #include "sm2_locl.h" 38 39 static EC_GROUP * 40 create_EC_group(const char *p_hex, const char *a_hex, const char *b_hex, 41 const char *x_hex, const char *y_hex, const char *order_hex, 42 const char *cof_hex) 43 { 44 BIGNUM *p = NULL; 45 BIGNUM *a = NULL; 46 BIGNUM *b = NULL; 47 BIGNUM *g_x = NULL; 48 BIGNUM *g_y = NULL; 49 BIGNUM *order = NULL; 50 BIGNUM *cof = NULL; 51 EC_POINT *generator = NULL; 52 EC_GROUP *group = NULL; 53 54 BN_hex2bn(&p, p_hex); 55 BN_hex2bn(&a, a_hex); 56 BN_hex2bn(&b, b_hex); 57 58 group = EC_GROUP_new_curve_GFp(p, a, b, NULL); 59 BN_free(p); 60 BN_free(a); 61 BN_free(b); 62 63 if (group == NULL) 64 return NULL; 65 66 generator = EC_POINT_new(group); 67 if (generator == NULL) 68 return NULL; 69 70 BN_hex2bn(&g_x, x_hex); 71 BN_hex2bn(&g_y, y_hex); 72 73 if (EC_POINT_set_affine_coordinates(group, generator, g_x, g_y, 74 NULL) == 0) 75 return NULL; 76 77 BN_free(g_x); 78 BN_free(g_y); 79 80 BN_hex2bn(&order, order_hex); 81 BN_hex2bn(&cof, cof_hex); 82 83 if (EC_GROUP_set_generator(group, generator, order, cof) == 0) 84 return NULL; 85 86 EC_POINT_free(generator); 87 BN_free(order); 88 BN_free(cof); 89 90 return group; 91 } 92 93 static int 94 test_sm2(const EC_GROUP *group, const EVP_MD *digest, const char *privkey_hex, 95 const char *message) 96 { 97 const size_t msg_len = strlen(message); 98 99 BIGNUM *priv = NULL; 100 EC_KEY *key = NULL; 101 EC_POINT *pt = NULL; 102 size_t ctext_len = 0; 103 uint8_t *ctext = NULL; 104 uint8_t *recovered = NULL; 105 size_t recovered_len = msg_len; 106 int rc = 0; 107 108 BN_hex2bn(&priv, privkey_hex); 109 110 key = EC_KEY_new(); 111 EC_KEY_set_group(key, group); 112 EC_KEY_set_private_key(key, priv); 113 114 pt = EC_POINT_new(group); 115 EC_POINT_mul(group, pt, priv, NULL, NULL, NULL); 116 117 EC_KEY_set_public_key(key, pt); 118 BN_free(priv); 119 EC_POINT_free(pt); 120 121 if (!SM2_ciphertext_size(key, digest, msg_len, &ctext_len)) 122 goto done; 123 ctext = calloc(1, ctext_len); 124 if (ctext == NULL) 125 goto done; 126 127 rc = SM2_encrypt(key, digest, (const uint8_t *)message, msg_len, ctext, &ctext_len); 128 129 if (rc == 0) 130 goto done; 131 132 recovered = calloc(1, msg_len); 133 if (recovered == NULL) 134 goto done; 135 rc = SM2_decrypt(key, digest, ctext, ctext_len, recovered, &recovered_len); 136 137 if (rc == 0) 138 goto done; 139 if (recovered_len != msg_len) 140 goto done; 141 if (memcmp(recovered, message, msg_len) != 0) 142 goto done; 143 144 rc = 1; 145 done: 146 147 free(ctext); 148 free(recovered); 149 EC_KEY_free(key); 150 return rc; 151 } 152 153 int 154 main(int argc, char **argv) 155 { 156 int rc; 157 EC_GROUP *test_group = 158 create_EC_group 159 ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 160 "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 161 "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 162 "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 163 "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 164 "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 165 "1"); 166 167 if (test_group == NULL) 168 return 1; 169 170 rc = test_sm2(test_group, EVP_sm3(), 171 "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0", 172 "encryption standard"); 173 174 if (rc == 0) 175 return 1; 176 177 /* Same test as above except using SHA-256 instead of SM3 */ 178 rc = test_sm2(test_group, EVP_sha256(), 179 "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0", 180 "encryption standard"); 181 if (rc == 0) 182 return 1; 183 184 EC_GROUP_free(test_group); 185 186 printf("SUCCESS\n"); 187 188 return 0; 189 } 190 191 #endif 192