helper.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <memory.h>
  4. #include <openssl/err.h>
  5. #include <openssl/obj_mac.h>
  6. #include <openssl/objects.h>
  7. #include <openssl/ec.h>
  8. void PrintBytes(const uint8_t* bytes, size_t len) {
  9. if (len == 0) return;
  10. for (size_t i = 0; i + 1< len; ++i)
  11. printf("%02X ", bytes[i]);
  12. printf("%02X", bytes[len - 1]);
  13. }
  14. // recommended curve only
  15. unsigned long PrintKeyInfo(const EC_KEY* lpcECKey, int* lperrno) {
  16. unsigned long ErrorCode = 0;
  17. const char* CurveName = NULL;
  18. const BIGNUM* PrivateKey = NULL;
  19. uint8_t* binPrivateKey = NULL;
  20. size_t binPrivateKeyLength = 0;
  21. const EC_POINT* PublicKey = NULL;
  22. BIGNUM* PublicKeyX = NULL;
  23. BIGNUM* PublicKeyY = NULL;
  24. uint8_t* binPublicKeyX = NULL;
  25. size_t binPublicKeyXLength = 0;
  26. uint8_t* binPublicKeyY = NULL;
  27. size_t binPublicKeyYLength = 0;
  28. // get curve name, no need to free
  29. int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(lpcECKey));
  30. CurveName = OBJ_nid2sn(nid);
  31. if (CurveName == NULL) {
  32. ErrorCode = ERR_get_error();
  33. goto On_PrintKeyInfo_Error;
  34. }
  35. // get private key, no need to free
  36. PrivateKey = EC_KEY_get0_private_key(lpcECKey);
  37. if (PrivateKey == NULL) {
  38. ErrorCode = ERR_get_error();
  39. goto On_PrintKeyInfo_Error;
  40. }
  41. // get public key, no need to free
  42. PublicKey = EC_KEY_get0_public_key(lpcECKey);
  43. if (PublicKey == NULL) {
  44. ErrorCode = ERR_get_error();
  45. goto On_PrintKeyInfo_Error;
  46. }
  47. // new BIGNUM, ready to receive Px
  48. PublicKeyX = BN_new();
  49. if (PublicKeyX == NULL) {
  50. ErrorCode = ERR_get_error();
  51. goto On_PrintKeyInfo_Error;
  52. }
  53. // new BIGNUM, ready to receive Py
  54. PublicKeyY = BN_new();
  55. if (PublicKeyY == NULL) {
  56. ErrorCode = ERR_get_error();
  57. goto On_PrintKeyInfo_Error;
  58. }
  59. // receive Px and Py
  60. if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(lpcECKey),
  61. PublicKey,
  62. PublicKeyX,
  63. PublicKeyY,
  64. NULL)) {
  65. ErrorCode = ERR_get_error();
  66. goto On_PrintKeyInfo_Error;
  67. }
  68. // determine binPrivateKey length
  69. binPrivateKeyLength = (size_t)BN_num_bytes(PrivateKey);
  70. if (binPrivateKeyLength == 0) {
  71. ErrorCode = ERR_get_error();
  72. goto On_PrintKeyInfo_Error;
  73. }
  74. // alloc binPrivateKeyX
  75. binPrivateKey = malloc(binPrivateKeyLength);
  76. if (binPrivateKey == NULL) {
  77. if (lperrno) *lperrno = errno;
  78. goto On_PrintKeyInfo_Error;
  79. }
  80. // determine binPublicKeyX length
  81. binPublicKeyXLength = (size_t)BN_num_bytes(PublicKeyX);
  82. if (binPublicKeyXLength == 0) {
  83. ErrorCode = ERR_get_error();
  84. goto On_PrintKeyInfo_Error;
  85. }
  86. // alloc binPublicKeyX
  87. binPublicKeyX = malloc(binPublicKeyXLength);
  88. if (binPublicKeyX == NULL) {
  89. if (lperrno) *lperrno = errno;
  90. goto On_PrintKeyInfo_Error;
  91. }
  92. // determine binPublicKeyY length
  93. binPublicKeyYLength = (size_t)BN_num_bytes(PublicKeyY);
  94. if (binPublicKeyYLength == 0) {
  95. ErrorCode = ERR_get_error();
  96. goto On_PrintKeyInfo_Error;
  97. }
  98. // alloc binPrivateKeyY
  99. binPublicKeyY = malloc(binPublicKeyYLength);
  100. if (binPublicKeyY == NULL) {
  101. if (lperrno) *lperrno = errno;
  102. goto On_PrintKeyInfo_Error;
  103. }
  104. // write to binPrivateKey
  105. if (!BN_bn2bin(PrivateKey, binPrivateKey)) {
  106. ErrorCode = ERR_get_error();
  107. goto On_PrintKeyInfo_Error;
  108. }
  109. // write to binPublicKeyX
  110. if (!BN_bn2bin(PublicKeyX, binPublicKeyX)) {
  111. ErrorCode = ERR_get_error();
  112. goto On_PrintKeyInfo_Error;
  113. }
  114. // write to binPublicKeyY
  115. if (!BN_bn2bin(PublicKeyY, binPublicKeyY)) {
  116. ErrorCode = ERR_get_error();
  117. goto On_PrintKeyInfo_Error;
  118. }
  119. printf("-----%s Private Key-----\n", CurveName);
  120. printf("Bin: ");
  121. PrintBytes(binPrivateKey, binPrivateKeyLength);
  122. printf("\n\n");
  123. printf("-----%s Public Key-----\n", CurveName);
  124. printf("Bin: X = ");
  125. PrintBytes(binPublicKeyX, binPublicKeyXLength);
  126. printf("\n");
  127. printf("Bin: Y = ");
  128. PrintBytes(binPublicKeyY, binPublicKeyYLength);
  129. printf("\n\n");
  130. On_PrintKeyInfo_Error:
  131. if (binPublicKeyY)
  132. free(binPublicKeyY);
  133. if (binPublicKeyX)
  134. free(binPublicKeyX);
  135. if (binPrivateKey)
  136. free(binPrivateKey);
  137. if (PublicKeyY)
  138. BN_free(PublicKeyY);
  139. if (PublicKeyX)
  140. BN_free(PublicKeyX);
  141. errno = 0;
  142. return ErrorCode;
  143. }
  144. size_t CustomBase32Encode(const void* __restrict src, size_t len,
  145. char* __restrict out_buf, size_t out_len) {
  146. static const char SubstitutionTable[33] = "0123456789ACDEFGHJKLMNPQRTUVWXYZ";
  147. if (len == 0)
  148. return 0;
  149. size_t minimum_buf_len = (8 * len + 4) / 5;
  150. if (out_len < minimum_buf_len)
  151. return minimum_buf_len;
  152. const uint8_t* src_bytes = src;
  153. size_t read_ptr = 0;
  154. int read_bits = 0;
  155. for (size_t i = 0; i < minimum_buf_len && read_ptr < len; ++i) {
  156. switch (read_bits) {
  157. case 0:
  158. case 1:
  159. case 2:
  160. out_buf[i] = SubstitutionTable[(src_bytes[read_ptr] >> (3 - read_bits)) % 32];
  161. read_bits += 5;
  162. break;
  163. case 3:
  164. out_buf[i] = SubstitutionTable[src_bytes[read_ptr] % 32];
  165. read_bits = 0;
  166. read_ptr++;
  167. break;
  168. case 4:
  169. case 5:
  170. case 6:
  171. case 7: {
  172. uint8_t temp = src_bytes[read_ptr++];
  173. temp &= ((1 << (8 - read_bits)) - 1);
  174. if (read_ptr < len) {
  175. temp |= src_bytes[read_ptr] >> (8 - (5 - (8 - read_bits))) << (8 - read_bits);
  176. out_buf[i] = SubstitutionTable[temp];
  177. read_bits = 5 - (8 - read_bits);
  178. } else {
  179. out_buf[i] = SubstitutionTable[temp];
  180. }
  181. }
  182. break;
  183. default:
  184. break;
  185. }
  186. }
  187. return minimum_buf_len;
  188. }
  189. size_t CustomBase32Decode(const char* __restrict src, size_t len,
  190. void* __restrict out_buf, size_t out_len) {
  191. static const uint8_t InverseSubstitutionTable[256] = {
  192. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  193. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  194. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  195. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff,
  196. 0xff,0x0a,0xff,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0xff,0x11,0x12,0x13,0x14,0x15,0xff,
  197. 0x16,0x17,0x18,0xff,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0xff,0xff,0xff,0xff,0xff,
  198. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  199. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  200. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  201. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  202. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  203. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  204. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  205. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  206. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  207. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
  208. };
  209. if (len == 0)
  210. return 0;
  211. size_t minimum_buf_len = (5 * len + 7) / 8;
  212. if (out_len < minimum_buf_len)
  213. return minimum_buf_len;
  214. for (size_t i = 0; i < len; ++i)
  215. if (InverseSubstitutionTable[(uint8_t)src[i]] == 0xff)
  216. return 0;
  217. memset(out_buf, 0, minimum_buf_len);
  218. size_t write_ptr = 0;
  219. int write_bits = 0;
  220. for (size_t i = 0; i < len && write_ptr < minimum_buf_len; ++i) {
  221. switch (write_bits) {
  222. case 0:
  223. case 1:
  224. case 2:
  225. ((uint8_t*)out_buf)[write_ptr] |= InverseSubstitutionTable[(uint8_t)src[i]] << (3 - write_bits);
  226. write_bits += 5;
  227. break;
  228. case 3:
  229. ((uint8_t*)out_buf)[write_ptr] |= InverseSubstitutionTable[(uint8_t)src[i]];
  230. write_bits = 0;
  231. write_ptr++;
  232. break;
  233. case 4:
  234. case 5:
  235. case 6:
  236. case 7: {
  237. uint8_t temp_l = InverseSubstitutionTable[(uint8_t)src[i]] & ((1 << (8 - write_bits)) - 1);
  238. uint8_t temp_h = InverseSubstitutionTable[(uint8_t)src[i]] & ~((1 << (8 - write_bits)) - 1);
  239. ((uint8_t*)out_buf)[write_ptr] |= temp_l;
  240. write_ptr++;
  241. ((uint8_t*)out_buf)[write_ptr] |= temp_h << 3;
  242. write_bits = 5 - (8 - write_bits);
  243. }
  244. break;
  245. default:
  246. break;
  247. }
  248. }
  249. return minimum_buf_len;
  250. }