Annotation of embedaddon/strongswan/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2017-2018 Tobias Brunner
                      3:  * Copyright (C) 2005 Jan Hutter
                      4:  * Copyright (C) 2005-2009 Martin Willi
                      5:  * Copyright (C) 2012-2019 Andreas Steffen
                      6:  * HSR Hochschule fuer Technik Rapperswil
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include <gmp.h>
                     20: #include <sys/stat.h>
                     21: #include <unistd.h>
                     22: #include <string.h>
                     23: 
                     24: #include "gmp_rsa_private_key.h"
                     25: #include "gmp_rsa_public_key.h"
                     26: 
                     27: #include <utils/debug.h>
                     28: #include <asn1/oid.h>
                     29: #include <asn1/asn1.h>
                     30: #include <asn1/asn1_parser.h>
                     31: #include <credentials/keys/signature_params.h>
                     32: 
                     33: #ifdef HAVE_MPZ_POWM_SEC
                     34: # undef mpz_powm
                     35: # define mpz_powm mpz_powm_sec
                     36: #endif
                     37: 
                     38: /**
                     39:  *  Public exponent to use for key generation.
                     40:  */
                     41: #define PUBLIC_EXPONENT 0x10001
                     42: 
                     43: typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t;
                     44: 
                     45: /**
                     46:  * Private data of a gmp_rsa_private_key_t object.
                     47:  */
                     48: struct private_gmp_rsa_private_key_t {
                     49:        /**
                     50:         * Public interface for this signer.
                     51:         */
                     52:        gmp_rsa_private_key_t public;
                     53: 
                     54:        /**
                     55:         * Public modulus.
                     56:         */
                     57:        mpz_t n;
                     58: 
                     59:        /**
                     60:         * Public exponent.
                     61:         */
                     62:        mpz_t e;
                     63: 
                     64:        /**
                     65:         * Private prime 1.
                     66:         */
                     67:        mpz_t p;
                     68: 
                     69:        /**
                     70:         * Private Prime 2.
                     71:         */
                     72:        mpz_t q;
                     73: 
                     74:        /**
                     75:         * Carmichael function m = lambda(n) = lcm(p-1,q-1).
                     76:        */
                     77:        mpz_t m;
                     78: 
                     79:        /**
                     80:         * Private exponent and optional secret sharing polynomial coefficients.
                     81:         */
                     82:        mpz_t *d;
                     83: 
                     84:        /**
                     85:         * Private exponent 1.
                     86:         */
                     87:        mpz_t exp1;
                     88: 
                     89:        /**
                     90:         * Private exponent 2.
                     91:         */
                     92:        mpz_t exp2;
                     93: 
                     94:        /**
                     95:         * Private coefficient.
                     96:         */
                     97:        mpz_t coeff;
                     98: 
                     99:        /**
                    100:         * Total number of private key shares
                    101:         */
                    102:        u_int shares;
                    103: 
                    104:        /**
                    105:         * Secret sharing threshold
                    106:         */
                    107:        u_int threshold;
                    108: 
                    109:        /**
                    110:         * Optional verification key (threshold > 1).
                    111:         */
                    112:        mpz_t v;
                    113: 
                    114:        /**
                    115:         * Keysize in bytes.
                    116:         */
                    117:        size_t k;
                    118: 
                    119:        /**
                    120:         * reference count
                    121:         */
                    122:        refcount_t ref;
                    123: };
                    124: 
                    125: /**
                    126:  * Convert a MP integer into a chunk_t
                    127:  */
                    128: chunk_t gmp_mpz_to_chunk(const mpz_t value)
                    129: {
                    130:        chunk_t n;
                    131: 
                    132:        n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE;
                    133:        n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
                    134:        if (n.ptr == NULL)
                    135:        {       /* if we have zero in "value", gmp returns NULL */
                    136:                n.len = 0;
                    137:        }
                    138:        return n;
                    139: }
                    140: 
                    141: /**
                    142:  * Auxiliary function overwriting private key material with zero bytes
                    143:  */
                    144: static void mpz_clear_sensitive(mpz_t z)
                    145: {
                    146:        size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
                    147:        uint8_t *zeros = alloca(len);
                    148: 
                    149:        memset(zeros, 0, len);
                    150:        /* overwrite mpz_t with zero bytes before clearing it */
                    151:        mpz_import(z, len, 1, 1, 1, 0, zeros);
                    152:        mpz_clear(z);
                    153: }
                    154: 
                    155: /**
                    156:  * Create a mpz prime of at least prime_size
                    157:  */
                    158: static status_t compute_prime(drbg_t *drbg, size_t prime_size, bool safe, mpz_t *p, mpz_t *q)
                    159: {
                    160:        chunk_t random_bytes;
                    161:        int count = 0;
                    162: 
                    163:        mpz_init(*p);
                    164:        mpz_init(*q);
                    165:        random_bytes = chunk_alloc(prime_size);
                    166: 
                    167:        do
                    168:        {
                    169:                if (!drbg->generate(drbg, random_bytes.len, random_bytes.ptr))
                    170:                {
                    171:                        DBG1(DBG_LIB, "failed to allocate random prime");
                    172:                        mpz_clear(*p);
                    173:                        mpz_clear(*q);
                    174:                        chunk_free(&random_bytes);
                    175:                        return FAILED;
                    176:                }
                    177: 
                    178:                /* make sure the two most significant bits are set */
                    179:                if (safe)
                    180:                {
                    181:                        random_bytes.ptr[0] &= 0x7F;
                    182:                        random_bytes.ptr[0] |= 0x60;
                    183:                        mpz_import(*q, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
                    184:                        do
                    185:                        {
                    186:                                count++;
                    187:                                mpz_nextprime (*q, *q);
                    188:                                mpz_mul_ui(*p, *q, 2);
                    189:                                mpz_add_ui(*p, *p, 1);
                    190:                        }
                    191:                        while (mpz_probab_prime_p(*p, 10) == 0);
                    192:                        DBG2(DBG_LIB, "safe prime found after %d iterations", count);
                    193:                }
                    194:                else
                    195:                {
                    196:                        random_bytes.ptr[0] |= 0xC0;
                    197:                        mpz_import(*p, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
                    198:                        mpz_nextprime (*p, *p);
                    199:                }
                    200:        }
                    201:        /* check if the prime isn't too large */
                    202:        while (((mpz_sizeinbase(*p, 2) + 7) / 8) > prime_size);
                    203: 
                    204:        chunk_clear(&random_bytes);
                    205: 
                    206:        /* additionally return p-1 */
                    207:        mpz_sub_ui(*q, *p, 1);
                    208: 
                    209:        return SUCCESS;
                    210: }
                    211: 
                    212: /**
                    213:  * PKCS#1 RSADP function
                    214:  */
                    215: static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data)
                    216: {
                    217:        mpz_t t1, t2;
                    218:        chunk_t decrypted;
                    219: 
                    220:        mpz_init(t1);
                    221:        mpz_init(t2);
                    222: 
                    223:        mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
                    224: 
                    225:        mpz_powm(t2, t1, this->exp1, this->p);  /* m1 = c^dP mod p */
                    226:        mpz_powm(t1, t1, this->exp2, this->q);  /* m2 = c^dQ mod Q */
                    227:        mpz_sub(t2, t2, t1);                                    /* h = qInv (m1 - m2) mod p */
                    228:        mpz_mod(t2, t2, this->p);
                    229:        mpz_mul(t2, t2, this->coeff);
                    230:        mpz_mod(t2, t2, this->p);
                    231: 
                    232:        mpz_mul(t2, t2, this->q);                               /* m = m2 + h q */
                    233:        mpz_add(t1, t1, t2);
                    234: 
                    235:        decrypted.len = this->k;
                    236:        decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
                    237:        if (decrypted.ptr == NULL)
                    238:        {
                    239:                decrypted.len = 0;
                    240:        }
                    241: 
                    242:        mpz_clear_sensitive(t1);
                    243:        mpz_clear_sensitive(t2);
                    244: 
                    245:        return decrypted;
                    246: }
                    247: 
                    248: /**
                    249:  * PKCS#1 RSASP1 function
                    250:  */
                    251: static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
                    252: {
                    253:        return rsadp(this, data);
                    254: }
                    255: 
                    256: /**
                    257:  * Hashes the data and builds the plaintext signature value with EMSA
                    258:  * PKCS#1 v1.5 padding.
                    259:  *
                    260:  * Allocates the signature data.
                    261:  */
                    262: bool gmp_emsa_pkcs1_signature_data(hash_algorithm_t hash_algorithm,
                    263:                                                                   chunk_t data, size_t keylen, chunk_t *em)
                    264: {
                    265:        chunk_t digestInfo = chunk_empty;
                    266: 
                    267:        if (hash_algorithm != HASH_UNKNOWN)
                    268:        {
                    269:                hasher_t *hasher;
                    270:                chunk_t hash;
                    271:                int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
                    272: 
                    273:                if (hash_oid == OID_UNKNOWN)
                    274:                {
                    275:                        return FALSE;
                    276:                }
                    277: 
                    278:                hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
                    279:                if (!hasher || !hasher->allocate_hash(hasher, data, &hash))
                    280:                {
                    281:                        DESTROY_IF(hasher);
                    282:                        return FALSE;
                    283:                }
                    284:                hasher->destroy(hasher);
                    285: 
                    286:                /* build DER-encoded digestInfo */
                    287:                digestInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
                    288:                                                asn1_algorithmIdentifier(hash_oid),
                    289:                                                asn1_wrap(ASN1_OCTET_STRING, "m", hash));
                    290: 
                    291:                data = digestInfo;
                    292:        }
                    293: 
                    294:        if (keylen < 11 || data.len > keylen - 11)
                    295:        {
                    296:                chunk_free(&digestInfo);
                    297:                DBG1(DBG_LIB, "signature value of %zu bytes is too long for key of "
                    298:                         "%zu bytes", data.len, keylen);
                    299:                return FALSE;
                    300:        }
                    301: 
                    302:        /* EM = 0x00 || 0x01 || PS || 0x00 || T.
                    303:         * PS = 0xFF padding, with length to fill em (at least 8 bytes)
                    304:         * T = encoded_hash
                    305:         */
                    306:        *em = chunk_alloc(keylen);
                    307: 
                    308:        /* fill em with padding */
                    309:        memset(em->ptr, 0xFF, em->len);
                    310:        /* set magic bytes */
                    311:        *(em->ptr) = 0x00;
                    312:        *(em->ptr+1) = 0x01;
                    313:        *(em->ptr + em->len - data.len - 1) = 0x00;
                    314:        /* set encoded hash */
                    315:        memcpy(em->ptr + em->len - data.len, data.ptr, data.len);
                    316: 
                    317:        chunk_clear(&digestInfo);
                    318:        return TRUE;
                    319: }
                    320: 
                    321: /**
                    322:  * Build a signature using the PKCS#1 EMSA scheme
                    323:  */
                    324: static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
                    325:                                                                           hash_algorithm_t hash_algorithm,
                    326:                                                                           chunk_t data, chunk_t *signature)
                    327: {
                    328:        chunk_t em;
                    329: 
                    330:        if (!gmp_emsa_pkcs1_signature_data(hash_algorithm, data, this->k, &em))
                    331:        {
                    332:                return FALSE;
                    333:        }
                    334: 
                    335:        /* build signature */
                    336:        *signature = rsasp1(this, em);
                    337: 
                    338:        chunk_free(&em);
                    339:        return TRUE;
                    340: }
                    341: 
                    342: /**
                    343:  * Build a signature using the PKCS#1 EMSA PSS scheme
                    344:  */
                    345: static bool build_emsa_pss_signature(private_gmp_rsa_private_key_t *this,
                    346:                                                                         rsa_pss_params_t *params, chunk_t data,
                    347:                                                                         chunk_t *signature)
                    348: {
                    349:        ext_out_function_t xof;
                    350:        hasher_t *hasher = NULL;
                    351:        rng_t *rng = NULL;
                    352:        xof_t *mgf = NULL;
                    353:        chunk_t hash, salt = chunk_empty, m, ps, db, dbmask, em;
                    354:        size_t embits, emlen, maskbits;
                    355:        bool success = FALSE;
                    356: 
                    357:        if (!params)
                    358:        {
                    359:                return FALSE;
                    360:        }
                    361:        xof = xof_mgf1_from_hash_algorithm(params->mgf1_hash);
                    362:        if (xof == XOF_UNDEFINED)
                    363:        {
                    364:                DBG1(DBG_LIB, "%N is not supported for MGF1", hash_algorithm_names,
                    365:                         params->mgf1_hash);
                    366:                return FALSE;
                    367:        }
                    368:        /* emBits = modBits - 1 */
                    369:        embits = mpz_sizeinbase(this->n, 2) - 1;
                    370:        /* emLen = ceil(emBits/8) */
                    371:        emlen = (embits + 7) / BITS_PER_BYTE;
                    372:        /* mHash = Hash(M) */
                    373:        hasher = lib->crypto->create_hasher(lib->crypto, params->hash);
                    374:        if (!hasher)
                    375:        {
                    376:                DBG1(DBG_LIB, "hash algorithm %N not supported",
                    377:                         hash_algorithm_names, params->hash);
                    378:                return FALSE;
                    379:        }
                    380:        hash = chunk_alloca(hasher->get_hash_size(hasher));
                    381:        if (!hasher->get_hash(hasher, data, hash.ptr))
                    382:        {
                    383:                goto error;
                    384:        }
                    385: 
                    386:        salt.len = params->salt_len;
                    387:        if (params->salt.len)
                    388:        {
                    389:                salt = params->salt;
                    390:        }
                    391:        if (emlen < (hash.len + salt.len + 2))
                    392:        {       /* too long */
                    393:                goto error;
                    394:        }
                    395:        if (salt.len && !params->salt.len)
                    396:        {
                    397:                salt = chunk_alloca(salt.len);
                    398:                rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
                    399:                if (!rng || !rng->get_bytes(rng, salt.len, salt.ptr))
                    400:                {
                    401:                        goto error;
                    402:                }
                    403:        }
                    404:        /* M' = 0x0000000000000000 | mHash | salt */
                    405:        m = chunk_cata("ccc",
                    406:                                   chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
                    407:                                   hash, salt);
                    408:        /* H = Hash(M') */
                    409:        if (!hasher->get_hash(hasher, m, hash.ptr))
                    410:        {
                    411:                goto error;
                    412:        }
                    413:        /* PS = 00...<padding depending on hash and salt length> */
                    414:        ps = chunk_alloca(emlen - salt.len - hash.len - 2);
                    415:        memset(ps.ptr, 0, ps.len);
                    416:        /* DB = PS | 0x01 | salt */
                    417:        db = chunk_cata("ccc", ps, chunk_from_chars(0x01), salt);
                    418:        /* dbMask = MGF(H, emLen - hLen - 1) */
                    419:        mgf = lib->crypto->create_xof(lib->crypto, xof);
                    420:        dbmask = chunk_alloca(db.len);
                    421:        if (!mgf)
                    422:        {
                    423:                DBG1(DBG_LIB, "%N not supported", ext_out_function_names, xof);
                    424:                goto error;
                    425:        }
                    426:        if (!mgf->set_seed(mgf, hash) ||
                    427:                !mgf->get_bytes(mgf, dbmask.len, dbmask.ptr))
                    428:        {
                    429:                goto error;
                    430:        }
                    431:        /* maskedDB = DB xor dbMask */
                    432:        memxor(db.ptr, dbmask.ptr, db.len);
                    433:        /* zero out unused bits */
                    434:        maskbits = (8 * emlen) - embits;
                    435:        if (maskbits)
                    436:        {
                    437:                db.ptr[0] &= (0xff >> maskbits);
                    438:        }
                    439:        /* EM = maskedDB | H | 0xbc */
                    440:        em = chunk_cata("ccc", db, hash, chunk_from_chars(0xbc));
                    441:        /* S = RSASP1(K, EM) */
                    442:        *signature = rsasp1(this, em);
                    443:        success = TRUE;
                    444: 
                    445: error:
                    446:        DESTROY_IF(hasher);
                    447:        DESTROY_IF(rng);
                    448:        DESTROY_IF(mgf);
                    449:        return success;
                    450: }
                    451: 
                    452: METHOD(private_key_t, get_type, key_type_t,
                    453:        private_gmp_rsa_private_key_t *this)
                    454: {
                    455:        return KEY_RSA;
                    456: }
                    457: 
                    458: METHOD(private_key_t, sign, bool,
                    459:        private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
                    460:        void *params, chunk_t data, chunk_t *signature)
                    461: {
                    462:        switch (scheme)
                    463:        {
                    464:                case SIGN_RSA_EMSA_PKCS1_NULL:
                    465:                        return build_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
                    466:                case SIGN_RSA_EMSA_PKCS1_SHA2_224:
                    467:                        return build_emsa_pkcs1_signature(this, HASH_SHA224, data, signature);
                    468:                case SIGN_RSA_EMSA_PKCS1_SHA2_256:
                    469:                        return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
                    470:                case SIGN_RSA_EMSA_PKCS1_SHA2_384:
                    471:                        return build_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
                    472:                case SIGN_RSA_EMSA_PKCS1_SHA2_512:
                    473:                        return build_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
                    474:                case SIGN_RSA_EMSA_PKCS1_SHA3_224:
                    475:                        return build_emsa_pkcs1_signature(this, HASH_SHA3_224, data, signature);
                    476:                case SIGN_RSA_EMSA_PKCS1_SHA3_256:
                    477:                        return build_emsa_pkcs1_signature(this, HASH_SHA3_256, data, signature);
                    478:                case SIGN_RSA_EMSA_PKCS1_SHA3_384:
                    479:                        return build_emsa_pkcs1_signature(this, HASH_SHA3_384, data, signature);
                    480:                case SIGN_RSA_EMSA_PKCS1_SHA3_512:
                    481:                        return build_emsa_pkcs1_signature(this, HASH_SHA3_512, data, signature);
                    482:                case SIGN_RSA_EMSA_PKCS1_SHA1:
                    483:                        return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
                    484:                case SIGN_RSA_EMSA_PKCS1_MD5:
                    485:                        return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
                    486:                case SIGN_RSA_EMSA_PSS:
                    487:                        return build_emsa_pss_signature(this, params, data, signature);
                    488:                default:
                    489:                        DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
                    490:                                 signature_scheme_names, scheme);
                    491:                        return FALSE;
                    492:        }
                    493: }
                    494: 
                    495: METHOD(private_key_t, decrypt, bool,
                    496:        private_gmp_rsa_private_key_t *this, encryption_scheme_t scheme,
                    497:        chunk_t crypto, chunk_t *plain)
                    498: {
                    499:        chunk_t em, stripped;
                    500:        bool success = FALSE;
                    501: 
                    502:        if (scheme != ENCRYPT_RSA_PKCS1)
                    503:        {
                    504:                DBG1(DBG_LIB, "encryption scheme %N not supported",
                    505:                         encryption_scheme_names, scheme);
                    506:                return FALSE;
                    507:        }
                    508:        /* rsa decryption using PKCS#1 RSADP */
                    509:        stripped = em = rsadp(this, crypto);
                    510: 
                    511:        /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */
                    512: 
                    513:        /* check for hex pattern 00 02 in decrypted message */
                    514:        if ((*stripped.ptr++ != 0x00) || (*(stripped.ptr++) != 0x02))
                    515:        {
                    516:                DBG1(DBG_LIB, "incorrect padding - probably wrong rsa key");
                    517:                goto end;
                    518:        }
                    519:        stripped.len -= 2;
                    520: 
                    521:        /* the plaintext data starts after first 0x00 byte */
                    522:        while (stripped.len-- > 0 && *stripped.ptr++ != 0x00)
                    523: 
                    524:        if (stripped.len == 0)
                    525:        {
                    526:                DBG1(DBG_LIB, "no plaintext data");
                    527:                goto end;
                    528:        }
                    529: 
                    530:        *plain = chunk_clone(stripped);
                    531:        success = TRUE;
                    532: 
                    533: end:
                    534:        chunk_clear(&em);
                    535:        return success;
                    536: }
                    537: 
                    538: METHOD(private_key_t, get_keysize, int,
                    539:        private_gmp_rsa_private_key_t *this)
                    540: {
                    541:        return mpz_sizeinbase(this->n, 2);
                    542: }
                    543: 
                    544: METHOD(private_key_t, get_public_key, public_key_t*,
                    545:        private_gmp_rsa_private_key_t *this)
                    546: {
                    547:        chunk_t n, e;
                    548:        public_key_t *public;
                    549: 
                    550:        n = gmp_mpz_to_chunk(this->n);
                    551:        e = gmp_mpz_to_chunk(this->e);
                    552: 
                    553:        public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
                    554:                                                BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
                    555:        chunk_free(&n);
                    556:        chunk_free(&e);
                    557: 
                    558:        return public;
                    559: }
                    560: 
                    561: METHOD(private_key_t, get_encoding, bool,
                    562:        private_gmp_rsa_private_key_t *this, cred_encoding_type_t type,
                    563:        chunk_t *encoding)
                    564: {
                    565:        chunk_t n, e, d, p, q, exp1, exp2, coeff;
                    566:        bool success;
                    567: 
                    568:        n = gmp_mpz_to_chunk(this->n);
                    569:        e = gmp_mpz_to_chunk(this->e);
                    570:        d = gmp_mpz_to_chunk(*this->d);
                    571:        p = gmp_mpz_to_chunk(this->p);
                    572:        q = gmp_mpz_to_chunk(this->q);
                    573:        exp1 = gmp_mpz_to_chunk(this->exp1);
                    574:        exp2 = gmp_mpz_to_chunk(this->exp2);
                    575:        coeff = gmp_mpz_to_chunk(this->coeff);
                    576: 
                    577:        success = lib->encoding->encode(lib->encoding,
                    578:                                                        type, NULL, encoding, CRED_PART_RSA_MODULUS, n,
                    579:                                                        CRED_PART_RSA_PUB_EXP, e, CRED_PART_RSA_PRIV_EXP, d,
                    580:                                                        CRED_PART_RSA_PRIME1, p, CRED_PART_RSA_PRIME2, q,
                    581:                                                        CRED_PART_RSA_EXP1, exp1, CRED_PART_RSA_EXP2, exp2,
                    582:                                                        CRED_PART_RSA_COEFF, coeff, CRED_PART_END);
                    583:        chunk_free(&n);
                    584:        chunk_free(&e);
                    585:        chunk_clear(&d);
                    586:        chunk_clear(&p);
                    587:        chunk_clear(&q);
                    588:        chunk_clear(&exp1);
                    589:        chunk_clear(&exp2);
                    590:        chunk_clear(&coeff);
                    591: 
                    592:        return success;
                    593: }
                    594: 
                    595: METHOD(private_key_t, get_fingerprint, bool,
                    596:        private_gmp_rsa_private_key_t *this, cred_encoding_type_t type, chunk_t *fp)
                    597: {
                    598:        chunk_t n, e;
                    599:        bool success;
                    600: 
                    601:        if (lib->encoding->get_cache(lib->encoding, type, this, fp))
                    602:        {
                    603:                return TRUE;
                    604:        }
                    605:        n = gmp_mpz_to_chunk(this->n);
                    606:        e = gmp_mpz_to_chunk(this->e);
                    607: 
                    608:        success = lib->encoding->encode(lib->encoding, type, this, fp,
                    609:                        CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
                    610:        chunk_free(&n);
                    611:        chunk_free(&e);
                    612: 
                    613:        return success;
                    614: }
                    615: 
                    616: METHOD(private_key_t, get_ref, private_key_t*,
                    617:        private_gmp_rsa_private_key_t *this)
                    618: {
                    619:        ref_get(&this->ref);
                    620:        return &this->public.key;
                    621: }
                    622: 
                    623: METHOD(private_key_t, destroy, void,
                    624:        private_gmp_rsa_private_key_t *this)
                    625: {
                    626:        if (ref_put(&this->ref))
                    627:        {
                    628:                int i;
                    629: 
                    630:                mpz_clear(this->n);
                    631:                mpz_clear(this->e);
                    632:                mpz_clear(this->v);
                    633:                mpz_clear_sensitive(this->p);
                    634:                mpz_clear_sensitive(this->q);
                    635:                mpz_clear_sensitive(this->m);
                    636:                mpz_clear_sensitive(this->exp1);
                    637:                mpz_clear_sensitive(this->exp2);
                    638:                mpz_clear_sensitive(this->coeff);
                    639: 
                    640:                for (i = 0; i < this->threshold; i++)
                    641:                {
                    642:                        mpz_clear_sensitive(*this->d + i);
                    643:                }
                    644:                free(this->d);
                    645: 
                    646:                lib->encoding->clear_cache(lib->encoding, this);
                    647:                free(this);
                    648:        }
                    649: }
                    650: 
                    651: /**
                    652:  * Check the loaded key if it is valid and usable
                    653:  */
                    654: static status_t check(private_gmp_rsa_private_key_t *this)
                    655: {
                    656:        mpz_t u, p1, q1;
                    657:        status_t status = SUCCESS;
                    658: 
                    659:        /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
                    660:         * We actually require more (for security).
                    661:         */
                    662:        if (this->k < 512 / BITS_PER_BYTE)
                    663:        {
                    664:                DBG1(DBG_LIB, "key shorter than 512 bits");
                    665:                return FAILED;
                    666:        }
                    667: 
                    668:        /* we picked a max modulus size to simplify buffer allocation */
                    669:        if (this->k > 8192 / BITS_PER_BYTE)
                    670:        {
                    671:                DBG1(DBG_LIB, "key larger than 8192 bits");
                    672:                return FAILED;
                    673:        }
                    674: 
                    675:        mpz_init(u);
                    676:        mpz_init(p1);
                    677:        mpz_init(q1);
                    678: 
                    679:        /* precompute p1 = p-1 and q1 = q-1 */
                    680:        mpz_sub_ui(p1, this->p, 1);
                    681:        mpz_sub_ui(q1, this->q, 1);
                    682: 
                    683:        /* check that n == p * q */
                    684:        mpz_mul(u, this->p, this->q);
                    685:        if (mpz_cmp(u, this->n) != 0)
                    686:        {
                    687:                status = FAILED;
                    688:        }
                    689: 
                    690:        /* check that e divides neither p-1 nor q-1 */
                    691:        mpz_mod(u, p1, this->e);
                    692:        if (mpz_cmp_ui(u, 0) == 0)
                    693:        {
                    694:                status = FAILED;
                    695:        }
                    696: 
                    697:        mpz_mod(u, q1, this->e);
                    698:        if (mpz_cmp_ui(u, 0) == 0)
                    699:        {
                    700:                status = FAILED;
                    701:        }
                    702: 
                    703:        /* check that d is e^-1 (mod lcm(p-1, q-1)) */
                    704:        /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
                    705:        mpz_lcm(this->m, p1, q1);
                    706:        mpz_mul(u, *this->d, this->e);
                    707:        mpz_mod(u, u, this->m);
                    708:        if (mpz_cmp_ui(u, 1) != 0)
                    709:        {
                    710:                status = FAILED;
                    711:        }
                    712: 
                    713:        /* check that exp1 is d mod (p-1) */
                    714:        mpz_mod(u, *this->d, p1);
                    715:        if (mpz_cmp(u, this->exp1) != 0)
                    716:        {
                    717:                status = FAILED;
                    718:        }
                    719: 
                    720:        /* check that exp2 is d mod (q-1) */
                    721:        mpz_mod(u, *this->d, q1);
                    722:        if (mpz_cmp(u, this->exp2) != 0)
                    723:        {
                    724:                status = FAILED;
                    725:        }
                    726: 
                    727:        /* check that coeff is (q^-1) mod p */
                    728:        mpz_mul(u, this->coeff, this->q);
                    729:        mpz_mod(u, u, this->p);
                    730:        if (mpz_cmp_ui(u, 1) != 0)
                    731:        {
                    732:                status = FAILED;
                    733:        }
                    734: 
                    735:        mpz_clear_sensitive(u);
                    736:        mpz_clear_sensitive(p1);
                    737:        mpz_clear_sensitive(q1);
                    738: 
                    739:        if (status != SUCCESS)
                    740:        {
                    741:                DBG1(DBG_LIB, "key integrity tests failed");
                    742:        }
                    743:        return status;
                    744: }
                    745: 
                    746: /**
                    747:  * Internal generic constructor
                    748:  */
                    749: static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
                    750: {
                    751:        private_gmp_rsa_private_key_t *this;
                    752: 
                    753:        INIT(this,
                    754:                .public = {
                    755:                        .key = {
                    756:                                .get_type = _get_type,
                    757:                                .sign = _sign,
                    758:                                .decrypt = _decrypt,
                    759:                                .get_keysize = _get_keysize,
                    760:                                .get_public_key = _get_public_key,
                    761:                                .equals = private_key_equals,
                    762:                                .belongs_to = private_key_belongs_to,
                    763:                                .get_fingerprint = _get_fingerprint,
                    764:                                .has_fingerprint = private_key_has_fingerprint,
                    765:                                .get_encoding = _get_encoding,
                    766:                                .get_ref = _get_ref,
                    767:                                .destroy = _destroy,
                    768:                        },
                    769:                },
                    770:                .threshold = 1,
                    771:                .ref = 1,
                    772:        );
                    773:        return this;
                    774: }
                    775: 
                    776: /**
                    777:  * See header.
                    778:  */
                    779: gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
                    780: {
                    781:        private_gmp_rsa_private_key_t *this;
                    782:        drbg_type_t drbg_type = DRBG_HMAC_SHA512;
                    783:        drbg_t* drbg;
                    784:        rng_t *rng;
                    785:        u_int strength = 256, key_size = 0, shares = 0, threshold = 1;
                    786:        bool safe_prime = FALSE, drbg_failed = FALSE, invert_failed = FALSE;
                    787:        mpz_t p, q, p1, q1;
                    788:        int i;
                    789: 
                    790: 
                    791:        while (TRUE)
                    792:        {
                    793:                switch (va_arg(args, builder_part_t))
                    794:                {
                    795:                        case BUILD_KEY_SIZE:
                    796:                                key_size = va_arg(args, u_int);
                    797:                                continue;
                    798:                        case BUILD_SAFE_PRIMES:
                    799:                                safe_prime = TRUE;
                    800:                                continue;
                    801:                        case BUILD_SHARES:
                    802:                                shares = va_arg(args, u_int);
                    803:                                continue;
                    804:                        case BUILD_THRESHOLD:
                    805:                                threshold = va_arg(args, u_int);
                    806:                                continue;
                    807:                        case BUILD_END:
                    808:                                break;
                    809:                        default:
                    810:                                return NULL;
                    811:                }
                    812:                break;
                    813:        }
                    814:        if (!key_size)
                    815:        {
                    816:                return NULL;
                    817:        }
                    818:        key_size = key_size / BITS_PER_BYTE;
                    819: 
                    820:        /* Initiate a NIST SP 800-90A DRBG fed by a true rng owned by the drbg */
                    821:        rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
                    822:        if (!rng)
                    823:        {
                    824:                DBG1(DBG_LIB, "no RNG of quality %N found", rng_quality_names, RNG_TRUE);
                    825:                return NULL;
                    826:        }
                    827:        drbg = lib->crypto->create_drbg(lib->crypto, drbg_type, strength, rng,
                    828:                                                                        chunk_empty);
                    829:        if (!drbg)
                    830:        {
                    831:                DBG1(DBG_LIB, "instantiation of %N failed", drbg_type_names, drbg_type);
                    832:                rng->destroy(rng);
                    833:                return NULL;
                    834:        }
                    835: 
                    836:        /* Get values of primes p and q  */
                    837:        if (compute_prime(drbg, key_size/2, safe_prime, &p, &p1) != SUCCESS)
                    838:        {
                    839:                drbg->destroy(drbg);
                    840:                return NULL;
                    841:        }
                    842:        if (compute_prime(drbg, key_size/2, safe_prime, &q, &q1) != SUCCESS)
                    843:        {
                    844:                mpz_clear(p);
                    845:                mpz_clear(p1);
                    846:                drbg->destroy(drbg);
                    847:                return NULL;
                    848:        }
                    849: 
                    850:        /* Swapping Primes so p is larger then q */
                    851:        if (mpz_cmp(p, q) < 0)
                    852:        {
                    853:                mpz_swap(p, q);
                    854:                mpz_swap(p1, q1);
                    855:        }
                    856: 
                    857:        /* Create and initialize RSA private key object */
                    858:        this = gmp_rsa_private_key_create_empty();
                    859:        *this->p = *p;
                    860:        *this->q = *q;
                    861: 
                    862:        /* allocate space for private exponent d with optional threshold scheme */
                    863:        this->shares = shares;
                    864:        this->threshold = threshold;
                    865:        this->d = malloc(threshold * sizeof(mpz_t));
                    866:        for (i = 0; i < threshold; i++)
                    867:        {
                    868:                mpz_init(this->d[i]);
                    869:        }
                    870: 
                    871:        mpz_init_set_ui(this->e, PUBLIC_EXPONENT);
                    872:        mpz_init(this->n);
                    873:        mpz_init(this->m);
                    874:        mpz_init(this->exp1);
                    875:        mpz_init(this->exp2);
                    876:        mpz_init(this->coeff);
                    877:        mpz_init(this->v);
                    878: 
                    879:        mpz_mul(this->n, p, q);                    /* n = p*q */
                    880:        mpz_lcm(this->m, p1, q1);                  /* m = lcm(p-1,q-1) */
                    881:        mpz_invert(this->d[0], this->e, this->m);  /* e has an inverse mod m */
                    882:        mpz_mod(this->exp1, this->d[0], p1);       /* exp1 = d mod p-1 */
                    883:        mpz_mod(this->exp2, this->d[0], q1);       /* exp2 = d mod q-1 */
                    884:        mpz_invert(this->coeff, q, p);             /* coeff = q^-1 mod p */
                    885: 
                    886:        invert_failed = mpz_cmp_ui(this->m, 0) == 0 ||
                    887:                                        mpz_cmp_ui(this->coeff, 0) == 0;
                    888: 
                    889:        /* generate and store random coefficients of secret sharing polynomial */
                    890:        if (threshold > 1)
                    891:        {
                    892:                chunk_t random_bytes;
                    893:                mpz_t u;
                    894: 
                    895:                mpz_init(u);
                    896:                random_bytes = chunk_alloc(key_size);
                    897: 
                    898:                for (i = 1; i < threshold; i++)
                    899:                {
                    900:                        if (!drbg->generate(drbg, random_bytes.len, random_bytes.ptr))
                    901:                        {
                    902:                                drbg_failed = TRUE;
                    903:                                continue;
                    904:                        }
                    905:                        mpz_import(this->d[i], random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
                    906:                        mpz_mod(this->d[i], this->d[i], this->m);
                    907:                }
                    908: 
                    909:                /* generate verification key v as a square number */
                    910:                do
                    911:                {
                    912:                        if (!drbg->generate(drbg, random_bytes.len, random_bytes.ptr))
                    913:                        {
                    914:                                drbg_failed = TRUE;
                    915:                                break;
                    916:                        }
                    917:                        mpz_import(this->v, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
                    918:                        mpz_mul(this->v, this->v, this->v);
                    919:                        mpz_mod(this->v, this->v, this->n);
                    920:                        mpz_gcd(u, this->v, this->n);
                    921:                }
                    922:                while (mpz_cmp_ui(u, 1) != 0);
                    923: 
                    924:                mpz_clear(u);
                    925:                chunk_clear(&random_bytes);
                    926:        }
                    927: 
                    928:        mpz_clear_sensitive(p1);
                    929:        mpz_clear_sensitive(q1);
                    930:        drbg->destroy(drbg);
                    931: 
                    932:        if (drbg_failed || invert_failed)
                    933:        {
                    934:                DBG1(DBG_LIB, "rsa key generation failed");
                    935:                destroy(this);
                    936:                return NULL;
                    937:        }
                    938: 
                    939:        /* set key size in bytes */
                    940:        this->k = key_size;
                    941: 
                    942:        return &this->public;
                    943: }
                    944: 
                    945: /**
                    946:  * Recover the primes from n, e and d using the algorithm described in
                    947:  * Appendix C of NIST SP 800-56B.
                    948:  */
                    949: static bool calculate_pq(private_gmp_rsa_private_key_t *this)
                    950: {
                    951:        gmp_randstate_t rstate;
                    952:        mpz_t k, r, g, y, n1, x;
                    953:        int i, t, j;
                    954:        bool success = FALSE;
                    955: 
                    956:        gmp_randinit_default(rstate);
                    957:        mpz_init(k);
                    958:        mpz_init(r);
                    959:        mpz_init(g);
                    960:        mpz_init(y);
                    961:        mpz_init(n1);
                    962:        mpz_init(x);
                    963:        /* k = (d * e) - 1 */
                    964:        mpz_mul(k, *this->d, this->e);
                    965:        mpz_sub_ui(k, k, 1);
                    966:        if (mpz_odd_p(k))
                    967:        {
                    968:                goto error;
                    969:        }
                    970:        /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
                    971:        mpz_set(r, k);
                    972:        for (t = 0; !mpz_odd_p(r); t++)
                    973:        {       /* r = r/2 */
                    974:                mpz_divexact_ui(r, r, 2);
                    975:        }
                    976:        /* we need n-1 below */
                    977:        mpz_sub_ui(n1, this->n, 1);
                    978:        for (i = 0; i < 100; i++)
                    979:        {       /* generate random integer g in [0, n-1] */
                    980:                mpz_urandomm(g, rstate, this->n);
                    981:                /* y = g^r mod n */
                    982:                mpz_powm(y, g, r, this->n);
                    983:                /* try again if y == 1 or y == n-1 */
                    984:                if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, n1) == 0)
                    985:                {
                    986:                        continue;
                    987:                }
                    988:                for (j = 0; j < t; j++)
                    989:                {       /* x = y^2 mod n */
                    990:                        mpz_powm_ui(x, y, 2, this->n);
                    991:                        /* stop if x == 1 */
                    992:                        if (mpz_cmp_ui(x, 1) == 0)
                    993:                        {
                    994:                                goto done;
                    995:                        }
                    996:                        /* retry with new g if x = n-1 */
                    997:                        if (mpz_cmp(x, n1) == 0)
                    998:                        {
                    999:                                break;
                   1000:                        }
                   1001:                        /* y = x */
                   1002:                        mpz_set(y, x);
                   1003:                }
                   1004:        }
                   1005:        goto error;
                   1006: 
                   1007: done:
                   1008:        /* p = gcd(y-1, n) */
                   1009:        mpz_sub_ui(y, y, 1);
                   1010:        mpz_gcd(this->p, y, this->n);
                   1011:        /* q = n/p */
                   1012:        mpz_divexact(this->q, this->n, this->p);
                   1013:        success = TRUE;
                   1014: 
                   1015: error:
                   1016:        mpz_clear_sensitive(k);
                   1017:        mpz_clear_sensitive(r);
                   1018:        mpz_clear_sensitive(g);
                   1019:        mpz_clear_sensitive(y);
                   1020:        mpz_clear_sensitive(x);
                   1021:        mpz_clear(n1);
                   1022:        gmp_randclear(rstate);
                   1023:        return success;
                   1024: }
                   1025: 
                   1026: /**
                   1027:  * See header.
                   1028:  */
                   1029: gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args)
                   1030: {
                   1031:        private_gmp_rsa_private_key_t *this;
                   1032:        chunk_t n, e, d, p, q, exp1, exp2, coeff;
                   1033: 
                   1034:        n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty;
                   1035:        while (TRUE)
                   1036:        {
                   1037:                switch (va_arg(args, builder_part_t))
                   1038:                {
                   1039:                        case BUILD_RSA_MODULUS:
                   1040:                                n = va_arg(args, chunk_t);
                   1041:                                continue;
                   1042:                        case BUILD_RSA_PUB_EXP:
                   1043:                                e = va_arg(args, chunk_t);
                   1044:                                continue;
                   1045:                        case BUILD_RSA_PRIV_EXP:
                   1046:                                d = va_arg(args, chunk_t);
                   1047:                                continue;
                   1048:                        case BUILD_RSA_PRIME1:
                   1049:                                p = va_arg(args, chunk_t);
                   1050:                                continue;
                   1051:                        case BUILD_RSA_PRIME2:
                   1052:                                q = va_arg(args, chunk_t);
                   1053:                                continue;
                   1054:                        case BUILD_RSA_EXP1:
                   1055:                                exp1 = va_arg(args, chunk_t);
                   1056:                                continue;
                   1057:                        case BUILD_RSA_EXP2:
                   1058:                                exp2 = va_arg(args, chunk_t);
                   1059:                                continue;
                   1060:                        case BUILD_RSA_COEFF:
                   1061:                                coeff = va_arg(args, chunk_t);
                   1062:                                continue;
                   1063:                        case BUILD_END:
                   1064:                                break;
                   1065:                        default:
                   1066:                                return NULL;
                   1067:                }
                   1068:                break;
                   1069:        }
                   1070: 
                   1071:        this = gmp_rsa_private_key_create_empty();
                   1072: 
                   1073:        this->d = malloc(sizeof(mpz_t));
                   1074:        mpz_init(this->n);
                   1075:        mpz_init(this->e);
                   1076:        mpz_init(*this->d);
                   1077:        mpz_init(this->p);
                   1078:        mpz_init(this->q);
                   1079:        mpz_init(this->m);
                   1080:        mpz_init(this->exp1);
                   1081:        mpz_init(this->exp2);
                   1082:        mpz_init(this->coeff);
                   1083:        mpz_init(this->v);
                   1084: 
                   1085:        mpz_import(this->n, n.len, 1, 1, 1, 0, n.ptr);
                   1086:        mpz_import(this->e, e.len, 1, 1, 1, 0, e.ptr);
                   1087:        mpz_import(*this->d, d.len, 1, 1, 1, 0, d.ptr);
                   1088:        if (p.len)
                   1089:        {
                   1090:                mpz_import(this->p, p.len, 1, 1, 1, 0, p.ptr);
                   1091:        }
                   1092:        if (q.len)
                   1093:        {
                   1094:                mpz_import(this->q, q.len, 1, 1, 1, 0, q.ptr);
                   1095:        }
                   1096:        if (!p.len && !q.len)
                   1097:        {       /* p and q missing in key, recalculate from n, e and d */
                   1098:                if (!calculate_pq(this))
                   1099:                {
                   1100:                        destroy(this);
                   1101:                        return NULL;
                   1102:                }
                   1103:        }
                   1104:        else if (!p.len)
                   1105:        {       /* p missing in key, recalculate: p = n / q */
                   1106:                mpz_divexact(this->p, this->n, this->q);
                   1107:        }
                   1108:        else if (!q.len)
                   1109:        {       /* q missing in key, recalculate: q = n / p */
                   1110:                mpz_divexact(this->q, this->n, this->p);
                   1111:        }
                   1112:        if (!exp1.len)
                   1113:        {       /* exp1 missing in key, recalculate: exp1 = d mod (p-1) */
                   1114:                mpz_sub_ui(this->exp1, this->p, 1);
                   1115:                mpz_mod(this->exp1, *this->d, this->exp1);
                   1116:        }
                   1117:        else
                   1118:        {
                   1119:                mpz_import(this->exp1, exp1.len, 1, 1, 1, 0, exp1.ptr);
                   1120:        }
                   1121:        if (!exp2.len)
                   1122:        {       /* exp2 missing in key, recalculate: exp2 = d mod (q-1) */
                   1123:                mpz_sub_ui(this->exp2, this->q, 1);
                   1124:                mpz_mod(this->exp2, *this->d, this->exp2);
                   1125:        }
                   1126:        else
                   1127:        {
                   1128:                mpz_import(this->exp2, exp2.len, 1, 1, 1, 0, exp2.ptr);
                   1129:        }
                   1130:        if (!coeff.len)
                   1131:        {       /* coeff missing in key, recalculate: coeff = q^-1 mod p */
                   1132:                mpz_invert(this->coeff, this->q, this->p);
                   1133:        }
                   1134:        else
                   1135:        {
                   1136:                mpz_import(this->coeff, coeff.len, 1, 1, 1, 0, coeff.ptr);
                   1137:        }
                   1138:        this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
                   1139:        if (check(this) != SUCCESS)
                   1140:        {
                   1141:                destroy(this);
                   1142:                return NULL;
                   1143:        }
                   1144:        return &this->public;
                   1145: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>