1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright 2014 by the Massachusetts Institute of Technology. 4 * All Rights Reserved. 5 * 6 * Export of this software from the United States of America may 7 * require a specific license from the United States Government. 8 * It is the responsibility of any person or organization contemplating 9 * export to obtain such a license before exporting. 10 * 11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 12 * distribute this software and its documentation for any purpose and 13 * without fee is hereby granted, provided that the above copyright 14 * notice appear in all copies and that both that copyright notice and 15 * this permission notice appear in supporting documentation, and that 16 * the name of M.I.T. not be used in advertising or publicity pertaining 17 * to distribution of the software without specific, written prior 18 * permission. Furthermore if you modify this software you must label 19 * your software as modified software and not distribute it in such a 20 * fashion that it might be confused with the original M.I.T. software. 21 * M.I.T. makes no representations about the suitability of 22 * this software for any purpose. It is provided "as is" without express 23 * or implied warranty. 24 */ 25 26 #include "k5-int.h" 27 #include "k5-hex.h" 28 #include "common.h" 29 #include "mglueP.h" 30 #include "gssapiP_krb5.h" 31 32 static const char inputstr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 33 "abcdefghijklmnopqrstuvwxyz123456789"; 34 35 /* For each test, out1 corresponds to key1 with an empty input, and out2 36 * corresponds to key2 with the above 61-byte input string. */ 37 static struct { 38 krb5_enctype enctype; 39 const char *key1; 40 const char *out1; 41 const char *key2; 42 const char *out2; 43 } tests[] = { 44 { ENCTYPE_DES3_CBC_SHA1, 45 "70378A19CD64134580C27C0115D6B34A1CF2FEECEF9886A2", 46 "9F8D127C520BB826BFF3E0FE5EF352389C17E0C073D9" 47 "AC4A333D644D21BA3EF24F4A886D143F85AC9F6377FB", 48 "3452A167DF1094BA1089E0A20E9E51ABEF1525922558B69E", 49 "6BF24FABC858F8DD9752E4FCD331BB831F238B5BE190" 50 "4EEA42E38F7A60C588F075C5C96A67E7F8B7BD0AECF4" }, 51 { ENCTYPE_ARCFOUR_HMAC, 52 "3BB3AE288C12B3B9D06B208A4151B3B6", 53 "9AEA11A3BCF3C53F1F91F5A0BA2132E2501ADF5F3C28" 54 "3C8A983AB88757CE865A22132D6100EAD63E9E291AFA", 55 "6DB7B33A01BD2B72F7655CB7B3D5FA0B", 56 "CDA9A544869FC84873B692663A82AFDA101C8611498B" 57 "A46138B01E927C9B95EEC953B562807434037837DDDF" }, 58 { ENCTYPE_AES128_CTS_HMAC_SHA1_96, 59 "6C742096EB896230312B73972FA28B5D", 60 "94208D982FC1BB7778128BDD77904420B45C9DA699F3" 61 "117BCE66E39602128EF0296611A6D191A5828530F20F", 62 "FA61138C109D834A477D24C7311BE6DA", 63 "0FAEDF0F842CC834FEE750487E1B622739286B975FE5" 64 "B7F45AB053143C75CA0DF5D3D4BBB80F6A616C7C9027" }, 65 { ENCTYPE_AES256_CTS_HMAC_SHA1_96, 66 "08FCDAFD5832611B73BA7B497FEBFF8C954B4B58031CAD9B977C3B8C25192FD6", 67 "E627EFC14EF5B6D629F830C7109DEA0D3D7D36E8CD57" 68 "A1F301C5452494A1928F05AFFBEE3360232209D3BE0D", 69 "F5B68B7823D8944F33F41541B4E4D38C9B2934F8D16334A796645B066152B4BE", 70 "112F2B2D878590653CCC7DE278E9F0AA46FA5A380B62" 71 "59F774CB7C134FCD37F61A50FD0D9F89BF8FE1A6B593" }, 72 { ENCTYPE_CAMELLIA128_CTS_CMAC, 73 "866E0466A178279A32AC0BDA92B72AEB", 74 "97FBB354BF341C3A160DCC86A7A910FDA824601DF677" 75 "68797BACEEBF5D250AE929DEC9760772084267F50A54", 76 "D4893FD37DA1A211E12DD1E03E0F03B7", 77 "1DEE2FF126CA563A2A2326B9DD3F0095013257414C83" 78 "FAD4398901013D55F367C82681186B7B2FE62F746BA4" }, 79 { ENCTYPE_CAMELLIA256_CTS_CMAC, 80 "203071B1AE77BD3D6FCE70174AF95C225B1CED46B35CF52B6479EFEB47E6B063", 81 "9B30020634C10FDA28420CEE7B96B70A90A771CED43A" 82 "D8346554163E5949CBAE2FB8EF36AFB6B32CE75116A0", 83 "A171AD582C1AFBBAD52ABD622EE6B6A14D19BF95C6914B2BA40FFD99A88EC660", 84 "A47CBB6E104DCC77E4DB48A7A474B977F2FB6A7A1AB6" 85 "52317D50508AE72B7BE2E4E4BA24164E029CBACF786B" }, 86 { ENCTYPE_AES128_CTS_HMAC_SHA256_128, 87 "089BCA48B105EA6EA77CA5D2F39DC5E7", 88 "ED1736209B7C59C9F6A3AE8CCC8A7C97ADFDD11688AD" 89 "F304F2F74252CBACD311A2D9253211FDA49745CE4F62", 90 "3705D96080C17728A0E800EAB6E0D23C", 91 "2BB41B183D76D8D5B30CBB049A7EFE9F350EFA058DC2" 92 "C4D868308D354A7B199BE6FD1F22B53C038BC6036581" }, 93 { ENCTYPE_AES256_CTS_HMAC_SHA384_192, 94 "45BD806DBF6A833A9CFFC1C94589A222367A79BC21C413718906E9F578A78467", 95 "1C613AE8B77A3B4D783F3DCE6C9178FC025E87F48A44" 96 "784A69CB5FC697FE266A6141905067EF78566D309085", 97 "6D404D37FAF79F9DF0D33568D320669800EB4836472EA8A026D16B7182460C52", 98 "D15944B0A44508D1E61213F6455F292A02298F870C01" 99 "A3F74AD0345A4A6651EBE101976E933F32D44F0B5947" }, 100 }; 101 102 /* Decode hexstr into out. No length checking. */ 103 static size_t 104 fromhex(const char *hexstr, unsigned char *out) 105 { 106 uint8_t *bytes; 107 size_t len; 108 109 if (k5_hex_decode(hexstr, &bytes, &len) != 0) 110 abort(); 111 memcpy(out, bytes, len); 112 free(bytes); 113 return len; 114 } 115 116 int 117 main(int argc, char *argv[]) 118 { 119 OM_uint32 minor, major; 120 gss_ctx_id_t context; 121 gss_union_ctx_id_desc uctx; 122 krb5_gss_ctx_id_rec kgctx; 123 krb5_key k1, k2; 124 krb5_keyblock kb1, kb2; 125 gss_buffer_desc in, out; 126 unsigned char k1buf[32], k2buf[32], outbuf[44]; 127 size_t i; 128 129 /* 130 * Fake up just enough of a krb5 GSS context to make gss_pseudo_random 131 * work, with chosen subkeys and acceptor subkeys. If we implement 132 * gss_import_lucid_sec_context, we can rewrite this to use public 133 * interfaces and stop using private headers and internal knowledge of the 134 * implementation. 135 */ 136 context = (gss_ctx_id_t)&uctx; 137 memset(&uctx, 0, sizeof(uctx)); 138 uctx.mech_type = &mech_krb5; 139 uctx.internal_ctx_id = (gss_ctx_id_t)&kgctx; 140 memset(&kgctx, 0, sizeof(kgctx)); 141 kgctx.k5_context = NULL; 142 kgctx.established = 1; 143 kgctx.have_acceptor_subkey = 1; 144 kb1.contents = k1buf; 145 kb2.contents = k2buf; 146 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { 147 /* Set up the keys for this test. */ 148 kb1.enctype = tests[i].enctype; 149 kb1.length = fromhex(tests[i].key1, k1buf); 150 check_k5err(NULL, "create_key", krb5_k_create_key(NULL, &kb1, &k1)); 151 kgctx.subkey = k1; 152 kb2.enctype = tests[i].enctype; 153 kb2.length = fromhex(tests[i].key2, k2buf); 154 check_k5err(NULL, "create_key", krb5_k_create_key(NULL, &kb2, &k2)); 155 kgctx.acceptor_subkey = k2; 156 157 /* Generate a PRF value with the subkey and an empty input, and compare 158 * it to the first expected output. */ 159 in.length = 0; 160 in.value = NULL; 161 major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_PARTIAL, &in, 162 44, &out); 163 check_gsserr("gss_pseudo_random", major, minor); 164 (void)fromhex(tests[i].out1, outbuf); 165 assert(out.length == 44 && memcmp(out.value, outbuf, 44) == 0); 166 (void)gss_release_buffer(&minor, &out); 167 168 /* Generate a PRF value with the acceptor subkey and the 61-byte input 169 * string, and compare it to the second expected output. */ 170 in.length = strlen(inputstr); 171 in.value = (char *)inputstr; 172 major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_FULL, &in, 44, 173 &out); 174 check_gsserr("gss_pseudo_random", major, minor); 175 (void)fromhex(tests[i].out2, outbuf); 176 assert(out.length == 44 && memcmp(out.value, outbuf, 44) == 0); 177 (void)gss_release_buffer(&minor, &out); 178 179 /* Also check that generating zero bytes of output works. */ 180 major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_FULL, &in, 0, 181 &out); 182 check_gsserr("gss_pseudo_random", major, minor); 183 assert(out.length == 0); 184 (void)gss_release_buffer(&minor, &out); 185 186 krb5_k_free_key(NULL, k1); 187 krb5_k_free_key(NULL, k2); 188 } 189 return 0; 190 } 191