1e71b7053SJung-uk Kim /* 258f35182SJung-uk Kim * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 874664626SKris Kennaway */ 974664626SKris Kennaway 1074664626SKris Kennaway #include <stdio.h> 11e71b7053SJung-uk Kim #include "internal/cryptlib.h" 1217f01e99SJung-uk Kim #include "bn_local.h" 1374664626SKris Kennaway 1474664626SKris Kennaway int BN_bn2mpi(const BIGNUM *a, unsigned char *d) 1574664626SKris Kennaway { 1674664626SKris Kennaway int bits; 1774664626SKris Kennaway int num = 0; 1874664626SKris Kennaway int ext = 0; 1974664626SKris Kennaway long l; 2074664626SKris Kennaway 2174664626SKris Kennaway bits = BN_num_bits(a); 2274664626SKris Kennaway num = (bits + 7) / 8; 236f9291ceSJung-uk Kim if (bits > 0) { 2474664626SKris Kennaway ext = ((bits & 0x07) == 0); 2574664626SKris Kennaway } 2674664626SKris Kennaway if (d == NULL) 2774664626SKris Kennaway return (num + 4 + ext); 2874664626SKris Kennaway 2974664626SKris Kennaway l = num + ext; 3074664626SKris Kennaway d[0] = (unsigned char)(l >> 24) & 0xff; 3174664626SKris Kennaway d[1] = (unsigned char)(l >> 16) & 0xff; 3274664626SKris Kennaway d[2] = (unsigned char)(l >> 8) & 0xff; 3374664626SKris Kennaway d[3] = (unsigned char)(l) & 0xff; 346f9291ceSJung-uk Kim if (ext) 356f9291ceSJung-uk Kim d[4] = 0; 3674664626SKris Kennaway num = BN_bn2bin(a, &(d[4 + ext])); 3774664626SKris Kennaway if (a->neg) 3874664626SKris Kennaway d[4] |= 0x80; 3974664626SKris Kennaway return (num + 4 + ext); 4074664626SKris Kennaway } 4174664626SKris Kennaway 42e71b7053SJung-uk Kim BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) 4374664626SKris Kennaway { 4474664626SKris Kennaway long len; 4574664626SKris Kennaway int neg = 0; 46e71b7053SJung-uk Kim BIGNUM *a = NULL; 4774664626SKris Kennaway 4858f35182SJung-uk Kim if (n < 4 || (d[0] & 0x80) != 0) { 4974664626SKris Kennaway BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); 50e71b7053SJung-uk Kim return NULL; 5174664626SKris Kennaway } 526f9291ceSJung-uk Kim len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) 536f9291ceSJung-uk Kim d[3]; 546f9291ceSJung-uk Kim if ((len + 4) != n) { 5574664626SKris Kennaway BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR); 56e71b7053SJung-uk Kim return NULL; 5774664626SKris Kennaway } 5874664626SKris Kennaway 59e71b7053SJung-uk Kim if (ain == NULL) 606f9291ceSJung-uk Kim a = BN_new(); 61e71b7053SJung-uk Kim else 62e71b7053SJung-uk Kim a = ain; 63e71b7053SJung-uk Kim 646f9291ceSJung-uk Kim if (a == NULL) 65e71b7053SJung-uk Kim return NULL; 6674664626SKris Kennaway 676f9291ceSJung-uk Kim if (len == 0) { 6874664626SKris Kennaway a->neg = 0; 6974664626SKris Kennaway a->top = 0; 70e71b7053SJung-uk Kim return a; 7174664626SKris Kennaway } 7274664626SKris Kennaway d += 4; 7374664626SKris Kennaway if ((*d) & 0x80) 7474664626SKris Kennaway neg = 1; 75e71b7053SJung-uk Kim if (BN_bin2bn(d, (int)len, a) == NULL) { 76e71b7053SJung-uk Kim if (ain == NULL) 77e71b7053SJung-uk Kim BN_free(a); 78e71b7053SJung-uk Kim return NULL; 79e71b7053SJung-uk Kim } 8074664626SKris Kennaway a->neg = neg; 816f9291ceSJung-uk Kim if (neg) { 8274664626SKris Kennaway BN_clear_bit(a, BN_num_bits(a) - 1); 8374664626SKris Kennaway } 843b4e3dcbSSimon L. B. Nielsen bn_check_top(a); 85e71b7053SJung-uk Kim return a; 8674664626SKris Kennaway } 87