1264377Sdes/* $OpenBSD: rsa.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */
257429Smarkm/*
357429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi>
457429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
557429Smarkm *                    All rights reserved
660576Skris *
765674Skris * As far as I am concerned, the code I have written for this software
865674Skris * can be used freely for any purpose.  Any derived versions of this
965674Skris * software must be clearly marked as such, and if the derived work is
1065674Skris * incompatible with the protocol description in the RFC file, it must be
1165674Skris * called by a name other than "ssh" or "Secure Shell".
1260576Skris *
1376262Sgreen *
1465674Skris * Copyright (c) 1999 Niels Provos.  All rights reserved.
1560576Skris *
1665674Skris * Redistribution and use in source and binary forms, with or without
1765674Skris * modification, are permitted provided that the following conditions
1865674Skris * are met:
1965674Skris * 1. Redistributions of source code must retain the above copyright
2065674Skris *    notice, this list of conditions and the following disclaimer.
2165674Skris * 2. Redistributions in binary form must reproduce the above copyright
2265674Skris *    notice, this list of conditions and the following disclaimer in the
2365674Skris *    documentation and/or other materials provided with the distribution.
2465674Skris *
2565674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2665674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2765674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2865674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2965674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3065674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3165674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3265674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3365674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3465674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3565674Skris *
3665674Skris *
3765674Skris * Description of the RSA algorithm can be found e.g. from the following
3865674Skris * sources:
3965674Skris *
4057429Smarkm *   Bruce Schneier: Applied Cryptography.  John Wiley & Sons, 1994.
4160576Skris *
4257429Smarkm *   Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to
4357429Smarkm *   Computer Security.  Prentice-Hall, 1989.
4460576Skris *
4557429Smarkm *   Man Young Rhee: Cryptography and Secure Data Communications.  McGraw-Hill,
4657429Smarkm *   1994.
4760576Skris *
4857429Smarkm *   R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications
4957429Smarkm *   System and Method.  US Patent 4,405,829, 1983.
5060576Skris *
5157429Smarkm *   Hans Riesel: Prime Numbers and Computer Methods for Factorization.
5257429Smarkm *   Birkhauser, 1994.
5360576Skris *
5465674Skris *   The RSA Frequently Asked Questions document by RSA Data Security,
5565674Skris *   Inc., 1995.
5660576Skris *
5765674Skris *   RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as
5865674Skris * included below:
5960576Skris *
6057429Smarkm *     [gone - had to be deleted - what a pity]
6165674Skris */
6257429Smarkm
6357429Smarkm#include "includes.h"
6457429Smarkm
65162856Sdes#include <sys/types.h>
66162856Sdes
67162856Sdes#include <stdarg.h>
68162856Sdes#include <string.h>
69162856Sdes
70162856Sdes#include "xmalloc.h"
7157429Smarkm#include "rsa.h"
7276262Sgreen#include "log.h"
7357429Smarkm
7457429Smarkmvoid
7557429Smarkmrsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
7657429Smarkm{
7776262Sgreen	u_char *inbuf, *outbuf;
7857429Smarkm	int len, ilen, olen;
7957429Smarkm
8057429Smarkm	if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
8157429Smarkm		fatal("rsa_public_encrypt() exponent too small or not odd");
8257429Smarkm
8357429Smarkm	olen = BN_num_bytes(key->n);
8457429Smarkm	outbuf = xmalloc(olen);
8557429Smarkm
8657429Smarkm	ilen = BN_num_bytes(in);
8757429Smarkm	inbuf = xmalloc(ilen);
8857429Smarkm	BN_bn2bin(in, inbuf);
8957429Smarkm
9057429Smarkm	if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key,
9157429Smarkm	    RSA_PKCS1_PADDING)) <= 0)
9276262Sgreen		fatal("rsa_public_encrypt() failed");
9357429Smarkm
94164149Sdes	if (BN_bin2bn(outbuf, len, out) == NULL)
95164149Sdes		fatal("rsa_public_encrypt: BN_bin2bn failed");
9657429Smarkm
97264377Sdes	explicit_bzero(outbuf, olen);
98264377Sdes	explicit_bzero(inbuf, ilen);
99255767Sdes	free(outbuf);
100255767Sdes	free(inbuf);
10157429Smarkm}
10257429Smarkm
10372397Skrisint
10457429Smarkmrsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
10557429Smarkm{
10676262Sgreen	u_char *inbuf, *outbuf;
10757429Smarkm	int len, ilen, olen;
10857429Smarkm
10957429Smarkm	olen = BN_num_bytes(key->n);
11057429Smarkm	outbuf = xmalloc(olen);
11157429Smarkm
11257429Smarkm	ilen = BN_num_bytes(in);
11357429Smarkm	inbuf = xmalloc(ilen);
11457429Smarkm	BN_bn2bin(in, inbuf);
11557429Smarkm
11657429Smarkm	if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key,
11772397Skris	    RSA_PKCS1_PADDING)) <= 0) {
11872397Skris		error("rsa_private_decrypt() failed");
11972397Skris	} else {
120164149Sdes		if (BN_bin2bn(outbuf, len, out) == NULL)
121164149Sdes			fatal("rsa_private_decrypt: BN_bin2bn failed");
12272397Skris	}
123264377Sdes	explicit_bzero(outbuf, olen);
124264377Sdes	explicit_bzero(inbuf, ilen);
125255767Sdes	free(outbuf);
126255767Sdes	free(inbuf);
12772397Skris	return len;
12857429Smarkm}
12957429Smarkm
13092559Sdes/* calculate p-1 and q-1 */
13157429Smarkmvoid
13292559Sdesrsa_generate_additional_parameters(RSA *rsa)
13357429Smarkm{
13476262Sgreen	BIGNUM *aux;
13576262Sgreen	BN_CTX *ctx;
13676262Sgreen
13792559Sdes	if ((aux = BN_new()) == NULL)
13892559Sdes		fatal("rsa_generate_additional_parameters: BN_new failed");
13992559Sdes	if ((ctx = BN_CTX_new()) == NULL)
14092559Sdes		fatal("rsa_generate_additional_parameters: BN_CTX_new failed");
14192559Sdes
142164149Sdes	if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
143164149Sdes	    (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
144164149Sdes	    (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
145164149Sdes	    (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
146164149Sdes		fatal("rsa_generate_additional_parameters: BN_sub/mod failed");
14776262Sgreen
14876262Sgreen	BN_clear_free(aux);
14976262Sgreen	BN_CTX_free(ctx);
15057429Smarkm}
15176262Sgreen
152