1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * project 2006. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * licensing@OpenSSL.org. 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */ 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/evp.h> 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#include <openssl/bn.h> 59b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/bytestring.h> 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/digest.h> 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/rsa.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 658ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan#include "../fipsmodule/rsa/internal.h" 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h" 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { 708f860b133896bf655e4342ecefe692d52df81d48Robert Sloan // See RFC 3279, section 2.3.1. 714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBB spki, algorithm, oid, null, key_bitstring; 724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || 734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || 744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || 754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || 764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || 774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || 784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_u8(&key_bitstring, 0 /* padding */) || 794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) || 804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_flush(out)) { 814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { 898f860b133896bf655e4342ecefe692d52df81d48Robert Sloan // See RFC 3279, section 2.3.1. 904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 918f860b133896bf655e4342ecefe692d52df81d48Robert Sloan // The parameters must be NULL. 924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBS null; 934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || 944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBS_len(&null) != 0 || 954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBS_len(params) != 0) { 964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 99b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root 10029c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan RSA *rsa = RSA_parse_public_key(key); 1014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (rsa == NULL || CBS_len(key) != 0) { 102b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 103b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root RSA_free(rsa); 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 106b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root 1074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin EVP_PKEY_assign_RSA(out, rsa); 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) == 0 && 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0; 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { 1174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBB pkcs8, algorithm, oid, null, private_key; 1184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || 1194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || 1204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || 1214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || 1224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || 1234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || 1244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || 1254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !RSA_marshal_private_key(&private_key, key->pkey.rsa) || 1264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !CBB_flush(out)) { 1274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { 1358f860b133896bf655e4342ecefe692d52df81d48Robert Sloan // Per RFC 3447, A.1, the parameters have type NULL. 1364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBS null; 1374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || 1384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBS_len(&null) != 0 || 1394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CBS_len(params) != 0) { 1404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin RSA *rsa = RSA_parse_private_key(key); 1454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (rsa == NULL || CBS_len(key) != 0) { 1464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 1474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin RSA_free(rsa); 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin EVP_PKEY_assign_RSA(out, rsa); 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int rsa_opaque(const EVP_PKEY *pkey) { 156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return RSA_is_opaque(pkey->pkey.rsa); 157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 159d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int int_rsa_size(const EVP_PKEY *pkey) { 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return RSA_size(pkey->pkey.rsa); 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 163d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int rsa_bits(const EVP_PKEY *pkey) { 16499319a18ffbf8991a8e752b4b8dacc9d39cdbd31Robert Sloan return RSA_bits(pkey->pkey.rsa); 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 167d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 169d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { 170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_PKEY_RSA, 1718f860b133896bf655e4342ecefe692d52df81d48Robert Sloan // 1.2.840.113549.1.1.1 1724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_pub_decode, 175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_pub_encode, 176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_pub_cmp, 177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_priv_decode, 179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_priv_encode, 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_opaque, 182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int_rsa_size, 184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley rsa_bits, 185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 0,0,0, 187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int_rsa_free, 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}; 190