1/* $OpenBSD: rsa.c,v 1.32 2014/06/24 01:13:21 djm Exp $ */ 2/* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * 7 * As far as I am concerned, the code I have written for this software 8 * can be used freely for any purpose. Any derived versions of this 9 * software must be clearly marked as such, and if the derived work is 10 * incompatible with the protocol description in the RFC file, it must be 11 * called by a name other than "ssh" or "Secure Shell". 12 * 13 * 14 * Copyright (c) 1999 Niels Provos. All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * 36 * 37 * Description of the RSA algorithm can be found e.g. from the following 38 * sources: 39 * 40 * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. 41 * 42 * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to 43 * Computer Security. Prentice-Hall, 1989. 44 * 45 * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill, 46 * 1994. 47 * 48 * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications 49 * System and Method. US Patent 4,405,829, 1983. 50 * 51 * Hans Riesel: Prime Numbers and Computer Methods for Factorization. 52 * Birkhauser, 1994. 53 * 54 * The RSA Frequently Asked Questions document by RSA Data Security, 55 * Inc., 1995. 56 * 57 * RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as 58 * included below: 59 * 60 * [gone - had to be deleted - what a pity] 61 */ 62 63#include "includes.h" 64 65#include <sys/types.h> 66 67#include <stdarg.h> 68#include <string.h> 69 70#include "rsa.h" 71#include "log.h" 72#include "ssherr.h" 73 74int 75rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) 76{ 77 u_char *inbuf = NULL, *outbuf = NULL; 78 int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; 79 80 if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) 81 return SSH_ERR_INVALID_ARGUMENT; 82 83 olen = BN_num_bytes(key->n); 84 if ((outbuf = malloc(olen)) == NULL) { 85 r = SSH_ERR_ALLOC_FAIL; 86 goto out; 87 } 88 89 ilen = BN_num_bytes(in); 90 if ((inbuf = malloc(ilen)) == NULL) { 91 r = SSH_ERR_ALLOC_FAIL; 92 goto out; 93 } 94 BN_bn2bin(in, inbuf); 95 96 if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, 97 RSA_PKCS1_PADDING)) <= 0) { 98 r = SSH_ERR_LIBCRYPTO_ERROR; 99 goto out; 100 } 101 102 if (BN_bin2bn(outbuf, len, out) == NULL) { 103 r = SSH_ERR_LIBCRYPTO_ERROR; 104 goto out; 105 } 106 r = 0; 107 108 out: 109 if (outbuf != NULL) { 110 explicit_bzero(outbuf, olen); 111 free(outbuf); 112 } 113 if (inbuf != NULL) { 114 explicit_bzero(inbuf, ilen); 115 free(inbuf); 116 } 117 return r; 118} 119 120int 121rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) 122{ 123 u_char *inbuf = NULL, *outbuf = NULL; 124 int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; 125 126 olen = BN_num_bytes(key->n); 127 if ((outbuf = malloc(olen)) == NULL) { 128 r = SSH_ERR_ALLOC_FAIL; 129 goto out; 130 } 131 132 ilen = BN_num_bytes(in); 133 if ((inbuf = malloc(ilen)) == NULL) { 134 r = SSH_ERR_ALLOC_FAIL; 135 goto out; 136 } 137 BN_bn2bin(in, inbuf); 138 139 if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, 140 RSA_PKCS1_PADDING)) <= 0) { 141 r = SSH_ERR_LIBCRYPTO_ERROR; 142 goto out; 143 } else if (BN_bin2bn(outbuf, len, out) == NULL) { 144 r = SSH_ERR_LIBCRYPTO_ERROR; 145 goto out; 146 } 147 r = 0; 148 out: 149 if (outbuf != NULL) { 150 explicit_bzero(outbuf, olen); 151 free(outbuf); 152 } 153 if (inbuf != NULL) { 154 explicit_bzero(inbuf, ilen); 155 free(inbuf); 156 } 157 return r; 158} 159 160/* calculate p-1 and q-1 */ 161int 162rsa_generate_additional_parameters(RSA *rsa) 163{ 164 BIGNUM *aux = NULL; 165 BN_CTX *ctx = NULL; 166 int r; 167 168 if ((ctx = BN_CTX_new()) == NULL) 169 return SSH_ERR_ALLOC_FAIL; 170 if ((aux = BN_new()) == NULL) { 171 r = SSH_ERR_ALLOC_FAIL; 172 goto out; 173 } 174 175 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || 176 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || 177 (BN_sub(aux, rsa->p, BN_value_one()) == 0) || 178 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { 179 r = SSH_ERR_LIBCRYPTO_ERROR; 180 goto out; 181 } 182 r = 0; 183 out: 184 BN_clear_free(aux); 185 BN_CTX_free(ctx); 186 return r; 187} 188 189