1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 12e1051a39Sopenharmony_ci#include "bn_local.h" 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ciint BN_bn2mpi(const BIGNUM *a, unsigned char *d) 15e1051a39Sopenharmony_ci{ 16e1051a39Sopenharmony_ci int bits; 17e1051a39Sopenharmony_ci int num = 0; 18e1051a39Sopenharmony_ci int ext = 0; 19e1051a39Sopenharmony_ci long l; 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci bits = BN_num_bits(a); 22e1051a39Sopenharmony_ci num = (bits + 7) / 8; 23e1051a39Sopenharmony_ci if (bits > 0) { 24e1051a39Sopenharmony_ci ext = ((bits & 0x07) == 0); 25e1051a39Sopenharmony_ci } 26e1051a39Sopenharmony_ci if (d == NULL) 27e1051a39Sopenharmony_ci return (num + 4 + ext); 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci l = num + ext; 30e1051a39Sopenharmony_ci d[0] = (unsigned char)(l >> 24) & 0xff; 31e1051a39Sopenharmony_ci d[1] = (unsigned char)(l >> 16) & 0xff; 32e1051a39Sopenharmony_ci d[2] = (unsigned char)(l >> 8) & 0xff; 33e1051a39Sopenharmony_ci d[3] = (unsigned char)(l) & 0xff; 34e1051a39Sopenharmony_ci if (ext) 35e1051a39Sopenharmony_ci d[4] = 0; 36e1051a39Sopenharmony_ci num = BN_bn2bin(a, &(d[4 + ext])); 37e1051a39Sopenharmony_ci if (a->neg) 38e1051a39Sopenharmony_ci d[4] |= 0x80; 39e1051a39Sopenharmony_ci return (num + 4 + ext); 40e1051a39Sopenharmony_ci} 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ciBIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) 43e1051a39Sopenharmony_ci{ 44e1051a39Sopenharmony_ci long len; 45e1051a39Sopenharmony_ci int neg = 0; 46e1051a39Sopenharmony_ci BIGNUM *a = NULL; 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_ci if (n < 4 || (d[0] & 0x80) != 0) { 49e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); 50e1051a39Sopenharmony_ci return NULL; 51e1051a39Sopenharmony_ci } 52e1051a39Sopenharmony_ci len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) 53e1051a39Sopenharmony_ci d[3]; 54e1051a39Sopenharmony_ci if ((len + 4) != n) { 55e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_BN, BN_R_ENCODING_ERROR); 56e1051a39Sopenharmony_ci return NULL; 57e1051a39Sopenharmony_ci } 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci if (ain == NULL) 60e1051a39Sopenharmony_ci a = BN_new(); 61e1051a39Sopenharmony_ci else 62e1051a39Sopenharmony_ci a = ain; 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci if (a == NULL) 65e1051a39Sopenharmony_ci return NULL; 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci if (len == 0) { 68e1051a39Sopenharmony_ci a->neg = 0; 69e1051a39Sopenharmony_ci a->top = 0; 70e1051a39Sopenharmony_ci return a; 71e1051a39Sopenharmony_ci } 72e1051a39Sopenharmony_ci d += 4; 73e1051a39Sopenharmony_ci if ((*d) & 0x80) 74e1051a39Sopenharmony_ci neg = 1; 75e1051a39Sopenharmony_ci if (BN_bin2bn(d, (int)len, a) == NULL) { 76e1051a39Sopenharmony_ci if (ain == NULL) 77e1051a39Sopenharmony_ci BN_free(a); 78e1051a39Sopenharmony_ci return NULL; 79e1051a39Sopenharmony_ci } 80e1051a39Sopenharmony_ci a->neg = neg; 81e1051a39Sopenharmony_ci if (neg) { 82e1051a39Sopenharmony_ci BN_clear_bit(a, BN_num_bits(a) - 1); 83e1051a39Sopenharmony_ci } 84e1051a39Sopenharmony_ci bn_check_top(a); 85e1051a39Sopenharmony_ci return a; 86e1051a39Sopenharmony_ci} 87