gost_test.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014, 2015  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 /* ! \file */
00020 
00021 #include <config.h>
00022 
00023 #include <atf-c.h>
00024 
00025 #include <stdio.h>
00026 #include <string.h>
00027 
00028 #include <isc/util.h>
00029 #include <isc/string.h>
00030 
00031 #include "dnstest.h"
00032 
00033 #ifdef HAVE_OPENSSL_GOST
00034 #include "../dst_gost.h"
00035 #include <openssl/err.h>
00036 #include <openssl/objects.h>
00037 #include <openssl/rsa.h>
00038 #include <openssl/engine.h>
00039 #endif
00040 
00041 #ifdef HAVE_PKCS11_GOST
00042 #include "../dst_gost.h"
00043 #include <pk11/internal.h>
00044 #define WANT_GOST_PARAMS
00045 #include <pk11/constants.h>
00046 #include <pkcs11/pkcs11.h>
00047 #endif
00048 
00049 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00050 /*
00051  * Test data from Wikipedia GOST (hash function)
00052  */
00053 
00054 unsigned char digest[ISC_GOST_DIGESTLENGTH];
00055 unsigned char buffer[1024];
00056 const char *s;
00057 char str[2 * ISC_GOST_DIGESTLENGTH + 1];
00058 int i = 0;
00059 
00060 isc_result_t
00061 tohexstr(unsigned char *d, unsigned int len, char *out);
00062 /*
00063  * Precondition: a hexadecimal number in *d, the length of that number in len,
00064  *   and a pointer to a character array to put the output (*out).
00065  * Postcondition: A String representation of the given hexadecimal number is
00066  *   placed into the array *out
00067  *
00068  * 'out' MUST point to an array of at least len * 2 + 1
00069  *
00070  * Return values: ISC_R_SUCCESS if the operation is sucessful
00071  */
00072 
00073 isc_result_t
00074 tohexstr(unsigned char *d, unsigned int len, char *out) {
00075 
00076         out[0]='\0';
00077         char c_ret[] = "AA";
00078         unsigned int j;
00079         strcat(out, "0x");
00080         for (j = 0; j < len; j++) {
00081                 sprintf(c_ret, "%02X", d[j]);
00082                 strcat(out, c_ret);
00083         }
00084         strcat(out, "\0");
00085         return (ISC_R_SUCCESS);
00086 }
00087 
00088 
00089 #define TEST_INPUT(x) (x), sizeof(x)-1
00090 
00091 typedef struct hash_testcase {
00092         const char *input;
00093         size_t input_len;
00094         const char *result;
00095         int repeats;
00096 } hash_testcase_t;
00097 
00098 ATF_TC(isc_gost_md);
00099 ATF_TC_HEAD(isc_gost_md, tc) {
00100         atf_tc_set_md_var(tc, "descr",
00101                           "GOST R 34.11-94 examples from Wikipedia");
00102 }
00103 ATF_TC_BODY(isc_gost_md, tc) {
00104         isc_gost_t gost;
00105         isc_result_t result;
00106 
00107         UNUSED(tc);
00108 
00109         /*
00110          * These are the various test vectors.  All of these are passed
00111          * through the hash function and the results are compared to the
00112          * result specified here.
00113          */
00114         hash_testcase_t testcases[] = {
00115                 /* Test 1 */
00116                 {
00117                         TEST_INPUT(""),
00118                         "0x981E5F3CA30C841487830F84FB433E1"
00119                         "3AC1101569B9C13584AC483234CD656C0",
00120                         1
00121                 },
00122                 /* Test 2 */
00123                 {
00124                         TEST_INPUT("a"),
00125                         "0xE74C52DD282183BF37AF0079C9F7805"
00126                         "5715A103F17E3133CEFF1AACF2F403011",
00127                         1
00128                 },
00129                 /* Test 3 */
00130                 {
00131                         TEST_INPUT("abc"),
00132                         "0xB285056DBF18D7392D7677369524DD1"
00133                         "4747459ED8143997E163B2986F92FD42C",
00134                         1
00135                 },
00136                 /* Test 4 */
00137                 {
00138                         TEST_INPUT("message digest"),
00139                         "0xBC6041DD2AA401EBFA6E9886734174F"
00140                         "EBDB4729AA972D60F549AC39B29721BA0",
00141                         1
00142                 },
00143                 /* Test 5 */
00144                 {
00145                         TEST_INPUT("The quick brown fox jumps "
00146                                    "over the lazy dog"),
00147                         "0x9004294A361A508C586FE53D1F1B027"
00148                         "46765E71B765472786E4770D565830A76",
00149                         1
00150                 },
00151 
00152                 /* Test 6 */
00153                 {
00154                         TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
00155                                    "fghijklmnopqrstuvwxyz0123456789"),
00156                         "0x73B70A39497DE53A6E08C67B6D4DB85"
00157                         "3540F03E9389299D9B0156EF7E85D0F61",
00158                         1
00159                 },
00160                 /* Test 7 */
00161                 {
00162                         TEST_INPUT("1234567890123456789012345678901"
00163                                    "2345678901234567890123456789012"
00164                                    "345678901234567890"),
00165                         "0x6BC7B38989B28CF93AE8842BF9D7529"
00166                         "05910A7528A61E5BCE0782DE43E610C90",
00167                         1
00168                 },
00169                 /* Test 8 */
00170                 {
00171                         TEST_INPUT("This is message, length=32 bytes"),
00172                         "0x2CEFC2F7B7BDC514E18EA57FA74FF35"
00173                         "7E7FA17D652C75F69CB1BE7893EDE48EB",
00174                         1
00175                 },
00176                 /* Test 9 */
00177                 {
00178                         TEST_INPUT("Suppose the original message "
00179                                    "has length = 50 bytes"),
00180                         "0xC3730C5CBCCACF915AC292676F21E8B"
00181                         "D4EF75331D9405E5F1A61DC3130A65011",
00182                         1
00183                 },
00184                 /* Test 10 */
00185                 {
00186                         TEST_INPUT("U") /* times 128 */,
00187                         "0x1C4AC7614691BBF427FA2316216BE8F"
00188                         "10D92EDFD37CD1027514C1008F649C4E8",
00189                         128
00190                 },
00191                 /* Test 11 */
00192                 {
00193                         TEST_INPUT("a") /* times 1000000 */,
00194                         "0x8693287AA62F9478F7CB312EC0866B6"
00195                         "C4E4A0F11160441E8F4FFCD2715DD554F",
00196                         1000000
00197                 },
00198                 { NULL, 0, NULL, 1 }
00199         };
00200 
00201         result = dns_test_begin(NULL, ISC_FALSE);
00202         ATF_REQUIRE(result == ISC_R_SUCCESS);
00203 
00204         hash_testcase_t *testcase = testcases;
00205 
00206         while (testcase->input != NULL && testcase->result != NULL) {
00207                 result = isc_gost_init(&gost);
00208                 ATF_REQUIRE(result == ISC_R_SUCCESS);
00209                 for(i = 0; i < testcase->repeats; i++) {
00210                         result = isc_gost_update(&gost,
00211                                         (const isc_uint8_t *) testcase->input,
00212                                         testcase->input_len);
00213                         ATF_REQUIRE(result == ISC_R_SUCCESS);
00214                 }
00215                 result = isc_gost_final(&gost, digest);
00216                 ATF_REQUIRE(result == ISC_R_SUCCESS);
00217                 tohexstr(digest, ISC_GOST_DIGESTLENGTH, str);
00218                 ATF_CHECK_STREQ(str, testcase->result);
00219 
00220                 testcase++;
00221         }
00222 
00223         dns_test_end();
00224 }
00225 
00226 ATF_TC(isc_gost_private);
00227 ATF_TC_HEAD(isc_gost_private, tc) {
00228   atf_tc_set_md_var(tc, "descr", "GOST R 34.10-2001 private key");
00229 }
00230 ATF_TC_BODY(isc_gost_private, tc) {
00231         isc_result_t result;
00232         unsigned char privraw[31] = {
00233                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
00234                 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
00235                 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
00236                 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
00237         };
00238 #ifdef HAVE_OPENSSL_GOST
00239         unsigned char rbuf[32];
00240         unsigned char privasn1[70] = {
00241                 0x30, 0x44, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
00242                 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
00243                 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
00244                 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
00245                 0x02, 0x1e, 0x01, 0x04, 0x21, 0x02, 0x1f, 0x01,
00246                 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
00247                 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
00248                 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
00249                 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
00250         };
00251         unsigned char abuf[71];
00252         unsigned char gost_dummy_key[71] = {
00253                 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
00254                 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
00255                 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
00256                 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
00257                 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b,
00258                 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5,
00259                 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65,
00260                 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63,
00261                 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6
00262         };
00263         EVP_PKEY *pkey;
00264         EC_KEY *eckey;
00265         BIGNUM *privkey;
00266         const BIGNUM *privkey1;
00267         const unsigned char *p;
00268         int len;
00269         unsigned char *q;
00270 
00271         result = dns_test_begin(NULL, ISC_FALSE);
00272         ATF_REQUIRE(result == ISC_R_SUCCESS);
00273 
00274         /* raw parse */
00275         privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL);
00276         ATF_REQUIRE(privkey != NULL);
00277         p = gost_dummy_key;
00278         pkey = NULL;
00279         ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
00280                                    (long) sizeof(gost_dummy_key)) != NULL);
00281         ATF_REQUIRE(pkey != NULL);
00282         ATF_REQUIRE(EVP_PKEY_bits(pkey) == 256);
00283         eckey = EVP_PKEY_get0(pkey);
00284         ATF_REQUIRE(eckey != NULL);
00285         ATF_REQUIRE(EC_KEY_set_private_key(eckey, privkey) == 1);
00286         BN_clear_free(privkey);
00287 
00288         /* asn1 tofile */
00289         len = i2d_PrivateKey(pkey, NULL);
00290         ATF_REQUIRE(len == 70);
00291         q = abuf;
00292         ATF_REQUIRE(i2d_PrivateKey(pkey, &q) == len);
00293         ATF_REQUIRE(memcmp(abuf, privasn1, len) == 0);
00294         EVP_PKEY_free(pkey);
00295 
00296         /* asn1 parse */
00297         p = privasn1;
00298         pkey = NULL;
00299         ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
00300                                    (long) len) != NULL);
00301         ATF_REQUIRE(pkey != NULL);
00302         eckey = EVP_PKEY_get0(pkey);
00303         ATF_REQUIRE(eckey != NULL);
00304         privkey1 = EC_KEY_get0_private_key(eckey);
00305         len = BN_num_bytes(privkey1);
00306         ATF_REQUIRE(len == 31);
00307         ATF_REQUIRE(BN_bn2bin(privkey1, rbuf) == len);
00308         ATF_REQUIRE(memcmp(rbuf, privraw, len) == 0);
00309 
00310         dns_test_end();
00311 #else
00312         CK_BBOOL truevalue = TRUE;
00313         CK_BBOOL falsevalue = FALSE;
00314         CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
00315         CK_KEY_TYPE keyType = CKK_GOSTR3410;
00316         CK_ATTRIBUTE keyTemplate[] =
00317         {
00318                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00319                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00320                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00321                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00322                 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00323                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00324                 { CKA_VALUE, privraw, sizeof(privraw) },
00325                 { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset,
00326                   (CK_ULONG) sizeof(pk11_gost_a_paramset) },
00327                 { CKA_GOSTR3411_PARAMS, pk11_gost_paramset,
00328                   (CK_ULONG) sizeof(pk11_gost_paramset) }
00329         };
00330         CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 };
00331         CK_BYTE sig[64];
00332         CK_ULONG siglen;
00333         pk11_context_t pk11_ctx;
00334 
00335         result = dns_test_begin(NULL, ISC_FALSE);
00336         ATF_REQUIRE(result == ISC_R_SUCCESS);
00337 
00338         /* create the private key */
00339         memset(&pk11_ctx, 0, sizeof(pk11_ctx));
00340         ATF_REQUIRE(pk11_get_session(&pk11_ctx, OP_GOST, ISC_TRUE,
00341                                      ISC_FALSE, ISC_FALSE, NULL,
00342                                      pk11_get_best_token(OP_GOST)) ==
00343                     ISC_R_SUCCESS);
00344         pk11_ctx.object = CK_INVALID_HANDLE;
00345         pk11_ctx.ontoken = ISC_FALSE;
00346         ATF_REQUIRE(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate,
00347                                         (CK_ULONG) 9, &pk11_ctx.object) ==
00348                     CKR_OK);
00349         ATF_REQUIRE(pk11_ctx.object != CK_INVALID_HANDLE);
00350 
00351         /* sign something */
00352         ATF_REQUIRE(pkcs_C_SignInit(pk11_ctx.session, &mech,
00353                                     pk11_ctx.object) == CKR_OK);
00354         siglen = 0;
00355         ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64,
00356                                 NULL, &siglen) == CKR_OK);
00357         ATF_REQUIRE(siglen == 64);
00358         ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64,
00359                                 sig, &siglen) == CKR_OK);
00360         ATF_REQUIRE(siglen == 64);
00361 
00362         dns_test_end();
00363 #endif
00364 };
00365 #else
00366 ATF_TC(untested);
00367 ATF_TC_HEAD(untested, tc) {
00368         atf_tc_set_md_var(tc, "descr", "skipping gost test");
00369 }
00370 ATF_TC_BODY(untested, tc) {
00371         UNUSED(tc);
00372         atf_tc_skip("GOST not available");
00373 }
00374 #endif
00375 /*
00376  * Main
00377  */
00378 ATF_TP_ADD_TCS(tp) {
00379 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00380         ATF_TP_ADD_TC(tp, isc_gost_md);
00381         ATF_TP_ADD_TC(tp, isc_gost_private);
00382 #else
00383         ATF_TP_ADD_TC(tp, untested);
00384 #endif
00385         return (atf_no_error());
00386 }
00387 

Generated on Tue Apr 28 17:41:01 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha