1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2000-2016 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 <openssl/asn1t.h> 13e1051a39Sopenharmony_ci#include <openssl/bn.h> 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci/* 16e1051a39Sopenharmony_ci * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER 17e1051a39Sopenharmony_ci * as a BIGNUM directly. Currently it ignores the sign which isn't a problem 18e1051a39Sopenharmony_ci * since all BIGNUMs used are non negative and anything that looks negative 19e1051a39Sopenharmony_ci * is normally due to an encoding error. 20e1051a39Sopenharmony_ci */ 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci#define BN_SENSITIVE 1 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_cistatic int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); 25e1051a39Sopenharmony_cistatic int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it); 26e1051a39Sopenharmony_cistatic void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_cistatic int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, 29e1051a39Sopenharmony_ci const ASN1_ITEM *it); 30e1051a39Sopenharmony_cistatic int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 31e1051a39Sopenharmony_ci int utype, char *free_cont, const ASN1_ITEM *it); 32e1051a39Sopenharmony_cistatic int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 33e1051a39Sopenharmony_ci int utype, char *free_cont, const ASN1_ITEM *it); 34e1051a39Sopenharmony_cistatic int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, 35e1051a39Sopenharmony_ci int indent, const ASN1_PCTX *pctx); 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_cistatic ASN1_PRIMITIVE_FUNCS bignum_pf = { 38e1051a39Sopenharmony_ci NULL, 0, 39e1051a39Sopenharmony_ci bn_new, 40e1051a39Sopenharmony_ci bn_free, 41e1051a39Sopenharmony_ci 0, 42e1051a39Sopenharmony_ci bn_c2i, 43e1051a39Sopenharmony_ci bn_i2c, 44e1051a39Sopenharmony_ci bn_print 45e1051a39Sopenharmony_ci}; 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_cistatic ASN1_PRIMITIVE_FUNCS cbignum_pf = { 48e1051a39Sopenharmony_ci NULL, 0, 49e1051a39Sopenharmony_ci bn_secure_new, 50e1051a39Sopenharmony_ci bn_free, 51e1051a39Sopenharmony_ci 0, 52e1051a39Sopenharmony_ci bn_secure_c2i, 53e1051a39Sopenharmony_ci bn_i2c, 54e1051a39Sopenharmony_ci bn_print 55e1051a39Sopenharmony_ci}; 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ciASN1_ITEM_start(BIGNUM) 58e1051a39Sopenharmony_ci ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" 59e1051a39Sopenharmony_ciASN1_ITEM_end(BIGNUM) 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_ciASN1_ITEM_start(CBIGNUM) 62e1051a39Sopenharmony_ci ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM" 63e1051a39Sopenharmony_ciASN1_ITEM_end(CBIGNUM) 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_cistatic int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 66e1051a39Sopenharmony_ci{ 67e1051a39Sopenharmony_ci *pval = (ASN1_VALUE *)BN_new(); 68e1051a39Sopenharmony_ci if (*pval != NULL) 69e1051a39Sopenharmony_ci return 1; 70e1051a39Sopenharmony_ci else 71e1051a39Sopenharmony_ci return 0; 72e1051a39Sopenharmony_ci} 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_cistatic int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 75e1051a39Sopenharmony_ci{ 76e1051a39Sopenharmony_ci *pval = (ASN1_VALUE *)BN_secure_new(); 77e1051a39Sopenharmony_ci if (*pval != NULL) 78e1051a39Sopenharmony_ci return 1; 79e1051a39Sopenharmony_ci else 80e1051a39Sopenharmony_ci return 0; 81e1051a39Sopenharmony_ci} 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_cistatic void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 84e1051a39Sopenharmony_ci{ 85e1051a39Sopenharmony_ci if (*pval == NULL) 86e1051a39Sopenharmony_ci return; 87e1051a39Sopenharmony_ci if (it->size & BN_SENSITIVE) 88e1051a39Sopenharmony_ci BN_clear_free((BIGNUM *)*pval); 89e1051a39Sopenharmony_ci else 90e1051a39Sopenharmony_ci BN_free((BIGNUM *)*pval); 91e1051a39Sopenharmony_ci *pval = NULL; 92e1051a39Sopenharmony_ci} 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_cistatic int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, 95e1051a39Sopenharmony_ci const ASN1_ITEM *it) 96e1051a39Sopenharmony_ci{ 97e1051a39Sopenharmony_ci BIGNUM *bn; 98e1051a39Sopenharmony_ci int pad; 99e1051a39Sopenharmony_ci if (*pval == NULL) 100e1051a39Sopenharmony_ci return -1; 101e1051a39Sopenharmony_ci bn = (BIGNUM *)*pval; 102e1051a39Sopenharmony_ci /* If MSB set in an octet we need a padding byte */ 103e1051a39Sopenharmony_ci if (BN_num_bits(bn) & 0x7) 104e1051a39Sopenharmony_ci pad = 0; 105e1051a39Sopenharmony_ci else 106e1051a39Sopenharmony_ci pad = 1; 107e1051a39Sopenharmony_ci if (cont) { 108e1051a39Sopenharmony_ci if (pad) 109e1051a39Sopenharmony_ci *cont++ = 0; 110e1051a39Sopenharmony_ci BN_bn2bin(bn, cont); 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci return pad + BN_num_bytes(bn); 113e1051a39Sopenharmony_ci} 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_cistatic int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 116e1051a39Sopenharmony_ci int utype, char *free_cont, const ASN1_ITEM *it) 117e1051a39Sopenharmony_ci{ 118e1051a39Sopenharmony_ci BIGNUM *bn; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (*pval == NULL && !bn_new(pval, it)) 121e1051a39Sopenharmony_ci return 0; 122e1051a39Sopenharmony_ci bn = (BIGNUM *)*pval; 123e1051a39Sopenharmony_ci if (!BN_bin2bn(cont, len, bn)) { 124e1051a39Sopenharmony_ci bn_free(pval, it); 125e1051a39Sopenharmony_ci return 0; 126e1051a39Sopenharmony_ci } 127e1051a39Sopenharmony_ci return 1; 128e1051a39Sopenharmony_ci} 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_cistatic int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 131e1051a39Sopenharmony_ci int utype, char *free_cont, const ASN1_ITEM *it) 132e1051a39Sopenharmony_ci{ 133e1051a39Sopenharmony_ci int ret; 134e1051a39Sopenharmony_ci BIGNUM *bn; 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_ci if (*pval == NULL && !bn_secure_new(pval, it)) 137e1051a39Sopenharmony_ci return 0; 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci ret = bn_c2i(pval, cont, len, utype, free_cont, it); 140e1051a39Sopenharmony_ci if (!ret) 141e1051a39Sopenharmony_ci return 0; 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ci /* Set constant-time flag for all secure BIGNUMS */ 144e1051a39Sopenharmony_ci bn = (BIGNUM *)*pval; 145e1051a39Sopenharmony_ci BN_set_flags(bn, BN_FLG_CONSTTIME); 146e1051a39Sopenharmony_ci return ret; 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_cistatic int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, 150e1051a39Sopenharmony_ci int indent, const ASN1_PCTX *pctx) 151e1051a39Sopenharmony_ci{ 152e1051a39Sopenharmony_ci if (!BN_print(out, *(BIGNUM **)pval)) 153e1051a39Sopenharmony_ci return 0; 154e1051a39Sopenharmony_ci if (BIO_puts(out, "\n") <= 0) 155e1051a39Sopenharmony_ci return 0; 156e1051a39Sopenharmony_ci return 1; 157e1051a39Sopenharmony_ci} 158