0000: 2f 2a 0a 20 2a 20 4b 65 79 20 44 65 72 69 76 61 /*. * Key Deriva
0010: 74 69 6f 6e 20 46 75 6e 63 74 69 6f 6e 20 28 4b tion Function (K
0020: 44 46 29 20 4d 6f 64 75 6c 65 0a 20 2a 0a 20 2a DF) Module. *. *
0030: 20 50 72 6f 76 69 64 65 73 20 63 6f 6d 6d 61 6e Provides comman
0040: 64 73 20 74 6f 20 64 65 72 69 76 65 20 6b 65 79 ds to derive key
0050: 73 2e 0a 20 2a 0a 20 2a 20 43 6f 70 79 72 69 67 s.. *. * Copyrig
0060: 68 74 20 28 43 29 20 32 30 32 33 20 42 72 69 61 ht (C) 2023 Bria
0070: 6e 20 4f 27 48 61 67 61 6e 0a 20 2a 0a 20 2a 2f n O'Hagan. *. */
0080: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 74 6c 73 49 ..#include "tlsI
0090: 6e 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 nt.h".#include "
00a0: 74 63 6c 4f 70 74 73 2e 68 22 0a 23 69 6e 63 6c tclOpts.h".#incl
00b0: 75 64 65 20 3c 6f 70 65 6e 73 73 6c 2f 63 72 79 ude <openssl/cry
00c0: 70 74 6f 2e 68 3e 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a pto.h>../*******
00d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
00e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
00f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0100: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f ************/../
0110: 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d *. *------------
0120: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0130: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0140: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0150: 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a 20 2a 20 44 65 -------. *. * De
0160: 72 69 76 65 4b 65 79 20 2d 2d 0a 20 2a 0a 20 2a riveKey --. *. *
0170: 09 50 4b 43 53 35 5f 50 42 4b 44 46 32 5f 48 4d .PKCS5_PBKDF2_HM
0180: 41 43 20 6b 65 79 20 64 65 72 69 76 61 74 69 6f AC key derivatio
0190: 6e 20 66 75 6e 63 74 69 6f 6e 20 28 4b 44 46 29 n function (KDF)
01a0: 20 73 70 65 63 69 66 69 65 64 20 62 79 20 50 4b specified by PK
01b0: 43 53 20 23 35 2e 0a 20 2a 09 53 65 65 20 52 46 CS #5.. *.See RF
01c0: 43 20 36 30 37 30 2e 0a 20 2a 0a 20 2a 20 52 65 C 6070.. *. * Re
01d0: 74 75 72 6e 73 3a 0a 20 2a 09 54 43 4c 5f 4f 4b turns:. *.TCL_OK
01e0: 20 6f 72 20 54 43 4c 5f 45 52 52 4f 52 0a 20 2a or TCL_ERROR. *
01f0: 0a 20 2a 20 53 69 64 65 20 65 66 66 65 63 74 73 . * Side effects
0200: 3a 0a 20 2a 09 53 65 74 73 20 72 65 73 75 6c 74 :. *.Sets result
0210: 20 74 6f 20 61 20 6c 69 73 74 20 6f 66 20 6b 65 to a list of ke
0220: 79 20 61 6e 64 20 69 76 20 76 61 6c 75 65 73 2c y and iv values,
0230: 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 6d 65 73 or an error mes
0240: 73 61 67 65 0a 20 2a 0a 20 2a 2d 2d 2d 2d 2d 2d sage. *. *------
0250: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0260: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0270: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0280: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a -------------. *
0290: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 44 65 72 /.static int Der
02a0: 69 76 65 4b 65 79 28 43 6c 69 65 6e 74 44 61 74 iveKey(ClientDat
02b0: 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 54 63 a clientData, Tc
02c0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 l_Interp *interp
02d0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f , int objc, Tcl_
02e0: 4f 62 6a 20 2a 63 6f 6e 73 74 20 6f 62 6a 76 5b Obj *const objv[
02f0: 5d 29 20 7b 0a 20 20 20 20 69 6e 74 20 6b 65 79 ]) {. int key
0300: 5f 6c 65 6e 20 3d 20 30 2c 20 6d 64 5f 6c 65 6e _len = 0, md_len
0310: 20 3d 20 30 2c 20 70 61 73 73 5f 6c 65 6e 20 3d = 0, pass_len =
0320: 20 30 2c 20 73 61 6c 74 5f 6c 65 6e 20 3d 20 30 0, salt_len = 0
0330: 3b 0a 20 20 20 20 69 6e 74 20 69 6b 6c 65 6e 2c ;. int iklen,
0340: 20 69 76 6c 65 6e 2c 20 69 74 65 72 20 3d 20 50 ivlen, iter = P
0350: 4b 43 53 35 5f 44 45 46 41 55 4c 54 5f 49 54 45 KCS5_DEFAULT_ITE
0360: 52 3b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 R;. unsigned
0370: 63 68 61 72 20 2a 70 61 73 73 77 64 20 3d 20 4e char *passwd = N
0380: 55 4c 4c 2c 20 2a 73 61 6c 74 20 3d 20 4e 55 4c ULL, *salt = NUL
0390: 4c 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a L;. Tcl_Obj *
03a0: 63 69 70 68 65 72 4f 62 6a 20 3d 20 4e 55 4c 4c cipherObj = NULL
03b0: 2c 20 2a 64 69 67 65 73 74 4f 62 6a 20 3d 20 4e , *digestObj = N
03c0: 55 4c 4c 2c 20 2a 70 61 73 73 77 64 4f 62 6a 20 ULL, *passwdObj
03d0: 3d 20 4e 55 4c 4c 2c 20 2a 73 61 6c 74 4f 62 6a = NULL, *saltObj
03e0: 20 3d 20 4e 55 4c 4c 2c 20 2a 72 65 73 75 6c 74 = NULL, *result
03f0: 4f 62 6a 3b 0a 20 20 20 20 63 6f 6e 73 74 20 45 Obj;. const E
0400: 56 50 5f 4d 44 20 2a 6d 64 20 3d 20 4e 55 4c 4c VP_MD *md = NULL
0410: 3b 0a 20 20 20 20 63 6f 6e 73 74 20 45 56 50 5f ;. const EVP_
0420: 43 49 50 48 45 52 20 2a 63 69 70 68 65 72 20 3d CIPHER *cipher =
0430: 20 4e 55 4c 4c 3b 0a 20 20 20 20 69 6e 74 20 6d NULL;. int m
0440: 61 78 20 3d 20 45 56 50 5f 4d 41 58 5f 4b 45 59 ax = EVP_MAX_KEY
0450: 5f 4c 45 4e 47 54 48 20 2b 20 45 56 50 5f 4d 41 _LENGTH + EVP_MA
0460: 58 5f 49 56 5f 4c 45 4e 47 54 48 2c 20 73 69 7a X_IV_LENGTH, siz
0470: 65 20 3d 20 6d 61 78 3b 0a 20 20 20 20 75 6e 73 e = max;. uns
0480: 69 67 6e 65 64 20 63 68 61 72 20 74 6d 70 6b 65 igned char tmpke
0490: 79 69 76 5b 45 56 50 5f 4d 41 58 5f 4b 45 59 5f yiv[EVP_MAX_KEY_
04a0: 4c 45 4e 47 54 48 20 2b 20 45 56 50 5f 4d 41 58 LENGTH + EVP_MAX
04b0: 5f 49 56 5f 4c 45 4e 47 54 48 5d 3b 0a 0a 20 20 _IV_LENGTH];..
04c0: 20 20 64 70 72 69 6e 74 66 28 22 43 61 6c 6c 65 dprintf("Calle
04d0: 64 22 29 3b 0a 0a 20 20 20 20 2f 2a 20 43 6c 65 d");.. /* Cle
04e0: 61 72 20 65 72 72 6f 72 73 20 2a 2f 0a 20 20 20 ar errors */.
04f0: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 Tcl_ResetResult
0500: 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 45 52 (interp);. ER
0510: 52 5f 63 6c 65 61 72 5f 65 72 72 6f 72 28 29 3b R_clear_error();
0520: 0a 0a 20 20 20 20 2f 2a 20 56 61 6c 69 64 61 74 .. /* Validat
0530: 65 20 61 72 67 20 63 6f 75 6e 74 20 2a 2f 0a 20 e arg count */.
0540: 20 20 20 69 66 20 28 6f 62 6a 63 20 3c 20 33 20 if (objc < 3
0550: 7c 7c 20 6f 62 6a 63 20 3e 20 31 31 29 20 7b 0a || objc > 11) {.
0560: 09 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 .Tcl_WrongNumArg
0570: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a s(interp, 1, obj
0580: 76 2c 20 22 5b 2d 63 69 70 68 65 72 20 63 69 70 v, "[-cipher cip
0590: 68 65 72 20 7c 20 2d 73 69 7a 65 20 6c 65 6e 67 her | -size leng
05a0: 74 68 5d 20 2d 64 69 67 65 73 74 20 64 69 67 65 th] -digest dige
05b0: 73 74 20 3f 2d 69 74 65 72 61 74 69 6f 6e 73 20 st ?-iterations
05c0: 63 6f 75 6e 74 3f 20 3f 2d 70 61 73 73 77 6f 72 count? ?-passwor
05d0: 64 20 73 74 72 69 6e 67 3f 20 3f 2d 73 61 6c 74 d string? ?-salt
05e0: 20 73 74 72 69 6e 67 3f 22 29 3b 0a 09 72 65 74 string?");..ret
05f0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 urn TCL_ERROR;.
0600: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 6e 69 }.. /* Ini
0610: 74 20 62 75 66 66 65 72 73 20 2a 2f 0a 20 20 20 t buffers */.
0620: 20 6d 65 6d 73 65 74 28 74 6d 70 6b 65 79 69 76 memset(tmpkeyiv
0630: 2c 20 30 2c 20 45 56 50 5f 4d 41 58 5f 4b 45 59 , 0, EVP_MAX_KEY
0640: 5f 4c 45 4e 47 54 48 20 2b 20 45 56 50 5f 4d 41 _LENGTH + EVP_MA
0650: 58 5f 49 56 5f 4c 45 4e 47 54 48 29 3b 0a 0a 20 X_IV_LENGTH);..
0660: 20 20 20 2f 2a 20 47 65 74 20 6f 70 74 69 6f 6e /* Get option
0670: 73 20 2a 2f 0a 20 20 20 20 66 6f 72 20 28 69 6e s */. for (in
0680: 74 20 69 64 78 20 3d 20 31 3b 20 69 64 78 20 3c t idx = 1; idx <
0690: 20 6f 62 6a 63 3b 20 69 64 78 2b 2b 29 20 7b 0a objc; idx++) {.
06a0: 09 63 68 61 72 20 2a 6f 70 74 20 3d 20 54 63 6c .char *opt = Tcl
06b0: 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 _GetStringFromOb
06c0: 6a 28 6f 62 6a 76 5b 69 64 78 5d 2c 20 4e 55 4c j(objv[idx], NUL
06d0: 4c 29 3b 0a 0a 09 69 66 20 28 6f 70 74 5b 30 5d L);...if (opt[0]
06e0: 20 21 3d 20 27 2d 27 29 20 7b 0a 09 20 20 20 20 != '-') {..
06f0: 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 4f 50 54 4f break;..}...OPTO
0700: 42 4a 28 22 2d 63 69 70 68 65 72 22 2c 20 63 69 BJ("-cipher", ci
0710: 70 68 65 72 4f 62 6a 29 3b 0a 09 4f 50 54 4f 42 pherObj);..OPTOB
0720: 4a 28 22 2d 64 69 67 65 73 74 22 2c 20 64 69 67 J("-digest", dig
0730: 65 73 74 4f 62 6a 29 3b 0a 09 4f 50 54 4f 42 4a estObj);..OPTOBJ
0740: 28 22 2d 68 61 73 68 22 2c 20 64 69 67 65 73 74 ("-hash", digest
0750: 4f 62 6a 29 3b 0a 09 4f 50 54 49 4e 54 28 22 2d Obj);..OPTINT("-
0760: 69 74 65 72 61 74 69 6f 6e 73 22 2c 20 69 74 65 iterations", ite
0770: 72 29 3b 0a 09 4f 50 54 4f 42 4a 28 22 2d 70 61 r);..OPTOBJ("-pa
0780: 73 73 77 6f 72 64 22 2c 20 70 61 73 73 77 64 4f ssword", passwdO
0790: 62 6a 29 3b 0a 09 4f 50 54 4f 42 4a 28 22 2d 73 bj);..OPTOBJ("-s
07a0: 61 6c 74 22 2c 20 73 61 6c 74 4f 62 6a 29 3b 0a alt", saltObj);.
07b0: 09 4f 50 54 49 4e 54 28 22 2d 73 69 7a 65 22 2c .OPTINT("-size",
07c0: 20 73 69 7a 65 29 3b 0a 0a 09 4f 50 54 42 41 44 size);...OPTBAD
07d0: 28 22 6f 70 74 69 6f 6e 22 2c 20 22 2d 63 69 70 ("option", "-cip
07e0: 68 65 72 2c 20 2d 64 69 67 65 73 74 2c 20 2d 69 her, -digest, -i
07f0: 74 65 72 61 74 69 6f 6e 73 2c 20 2d 70 61 73 73 terations, -pass
0800: 77 6f 72 64 2c 20 2d 73 61 6c 74 2c 20 6f 72 20 word, -salt, or
0810: 2d 73 69 7a 65 20 6f 70 74 69 6f 6e 22 29 3b 0a -size option");.
0820: 09 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f .return TCL_ERRO
0830: 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a R;. }.. /*
0840: 20 56 61 6c 69 64 61 74 65 20 6f 70 74 69 6f 6e Validate option
0850: 73 20 2a 2f 0a 20 20 20 20 69 66 20 28 63 69 70 s */. if (cip
0860: 68 65 72 4f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 herObj != NULL)
0870: 7b 0a 09 63 68 61 72 20 2a 6e 61 6d 65 20 3d 20 {..char *name =
0880: 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61 79 Tcl_GetByteArray
0890: 46 72 6f 6d 4f 62 6a 28 63 69 70 68 65 72 4f 62 FromObj(cipherOb
08a0: 6a 2c 20 4e 55 4c 4c 29 3b 0a 09 63 69 70 68 65 j, NULL);..ciphe
08b0: 72 20 3d 20 45 56 50 5f 67 65 74 5f 63 69 70 68 r = EVP_get_ciph
08c0: 65 72 62 79 6e 61 6d 65 28 6e 61 6d 65 29 3b 0a erbyname(name);.
08d0: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 28 64 69 }. if (di
08e0: 67 65 73 74 4f 62 6a 20 21 3d 20 4e 55 4c 4c 29 gestObj != NULL)
08f0: 20 7b 0a 09 63 68 61 72 20 2a 6e 61 6d 65 20 3d {..char *name =
0900: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 Tcl_GetStringFr
0910: 6f 6d 4f 62 6a 28 64 69 67 65 73 74 4f 62 6a 2c omObj(digestObj,
0920: 20 26 6d 64 5f 6c 65 6e 29 3b 0a 09 6d 64 20 3d &md_len);..md =
0930: 20 45 56 50 5f 67 65 74 5f 64 69 67 65 73 74 62 EVP_get_digestb
0940: 79 6e 61 6d 65 28 6e 61 6d 65 29 3b 0a 20 20 20 yname(name);.
0950: 20 7d 20 65 6c 73 65 20 7b 0a 09 54 63 6c 5f 41 } else {..Tcl_A
0960: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 ppendResult(inte
0970: 72 70 2c 20 22 4e 6f 20 64 69 67 65 73 74 20 73 rp, "No digest s
0980: 70 65 63 69 66 69 65 64 22 2c 20 4e 55 4c 4c 29 pecified", NULL)
0990: 3b 0a 09 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 ;..return TCL_ER
09a0: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 ROR;. }. i
09b0: 66 20 28 70 61 73 73 77 64 4f 62 6a 20 21 3d 20 f (passwdObj !=
09c0: 4e 55 4c 4c 29 20 7b 0a 09 70 61 73 73 77 64 20 NULL) {..passwd
09d0: 3d 20 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 = Tcl_GetByteArr
09e0: 61 79 46 72 6f 6d 4f 62 6a 28 70 61 73 73 77 64 ayFromObj(passwd
09f0: 4f 62 6a 2c 20 26 70 61 73 73 5f 6c 65 6e 29 3b Obj, &pass_len);
0a00: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 28 73 . }. if (s
0a10: 61 6c 74 4f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 altObj != NULL)
0a20: 7b 0a 09 73 61 6c 74 20 3d 20 54 63 6c 5f 47 65 {..salt = Tcl_Ge
0a30: 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d 4f 62 tByteArrayFromOb
0a40: 6a 28 73 61 6c 74 4f 62 6a 2c 20 26 73 61 6c 74 j(saltObj, &salt
0a50: 5f 6c 65 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 20 _len);. }.
0a60: 20 69 66 20 28 69 74 65 72 20 3c 20 31 29 20 7b if (iter < 1) {
0a70: 0a 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 ..Tcl_SetObjResu
0a80: 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4f lt(interp, Tcl_O
0a90: 62 6a 50 72 69 6e 74 66 28 22 49 6e 76 61 6c 69 bjPrintf("Invali
0aa0: 64 20 69 74 65 72 61 74 69 6f 6e 73 20 63 6f 75 d iterations cou
0ab0: 6e 74 20 25 64 3a 20 6d 75 73 74 20 62 65 20 3e nt %d: must be >
0ac0: 20 30 22 2c 20 69 74 65 72 29 29 3b 0a 09 72 65 0", iter));..re
0ad0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a turn TCL_ERROR;.
0ae0: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 28 73 69 }. if (si
0af0: 7a 65 20 3c 20 31 20 7c 7c 20 73 69 7a 65 20 3e ze < 1 || size >
0b00: 20 6d 61 78 29 20 7b 0a 09 54 63 6c 5f 53 65 74 max) {..Tcl_Set
0b10: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 ObjResult(interp
0b20: 2c 20 54 63 6c 5f 4f 62 6a 50 72 69 6e 74 66 28 , Tcl_ObjPrintf(
0b30: 22 49 6e 76 61 6c 69 64 20 64 65 72 69 76 65 64 "Invalid derived
0b40: 20 6b 65 79 20 6c 65 6e 67 74 68 20 25 64 3a 20 key length %d:
0b50: 6d 75 73 74 20 62 65 20 30 20 3c 20 73 69 7a 65 must be 0 < size
0b60: 20 3c 3d 20 25 64 22 2c 20 73 69 7a 65 2c 20 6d <= %d", size, m
0b70: 61 78 29 29 3b 0a 09 72 65 74 75 72 6e 20 54 43 ax));..return TC
0b80: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a L_ERROR;. }..
0b90: 20 20 20 20 69 66 20 28 63 69 70 68 65 72 20 3d if (cipher =
0ba0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 69 66 20 28 73 = NULL) {..if (s
0bb0: 69 7a 65 20 3e 20 6d 61 78 29 20 73 69 7a 65 20 ize > max) size
0bc0: 3d 20 6d 61 78 3b 0a 09 69 6b 6c 65 6e 20 3d 20 = max;..iklen =
0bd0: 73 69 7a 65 3b 0a 09 69 76 6c 65 6e 20 3d 20 30 size;..ivlen = 0
0be0: 3b 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09 ;. } else {..
0bf0: 69 6b 6c 65 6e 20 3d 20 45 56 50 5f 43 49 50 48 iklen = EVP_CIPH
0c00: 45 52 5f 6b 65 79 5f 6c 65 6e 67 74 68 28 63 69 ER_key_length(ci
0c10: 70 68 65 72 29 3b 0a 09 69 76 6c 65 6e 20 3d 20 pher);..ivlen =
0c20: 45 56 50 5f 43 49 50 48 45 52 5f 69 76 5f 6c 65 EVP_CIPHER_iv_le
0c30: 6e 67 74 68 28 63 69 70 68 65 72 29 3b 0a 09 73 ngth(cipher);..s
0c40: 69 7a 65 20 3d 20 69 6b 6c 65 6e 2b 69 76 6c 65 ize = iklen+ivle
0c50: 6e 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a n;. }.. /*
0c60: 20 50 65 72 66 6f 72 6d 20 70 61 73 73 77 6f 72 Perform passwor
0c70: 64 20 64 65 72 69 76 61 74 69 6f 6e 20 2a 2f 0a d derivation */.
0c80: 20 20 20 20 69 66 20 28 21 50 4b 43 53 35 5f 50 if (!PKCS5_P
0c90: 42 4b 44 46 32 5f 48 4d 41 43 28 70 61 73 73 77 BKDF2_HMAC(passw
0ca0: 64 2c 20 70 61 73 73 5f 6c 65 6e 2c 20 73 61 6c d, pass_len, sal
0cb0: 74 2c 20 73 61 6c 74 5f 6c 65 6e 2c 20 69 74 65 t, salt_len, ite
0cc0: 72 2c 20 6d 64 2c 20 73 69 7a 65 2c 20 74 6d 70 r, md, size, tmp
0cd0: 6b 65 79 69 76 29 29 20 7b 0a 09 54 63 6c 5f 41 keyiv)) {..Tcl_A
0ce0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 ppendResult(inte
0cf0: 72 70 2c 20 22 4b 65 79 20 64 65 72 69 76 61 74 rp, "Key derivat
0d00: 69 6f 6e 20 66 61 69 6c 65 64 3a 20 22 2c 20 52 ion failed: ", R
0d10: 45 41 53 4f 4e 28 29 2c 20 4e 55 4c 4c 29 3b 0a EASON(), NULL);.
0d20: 09 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f .return TCL_ERRO
0d30: 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 2f 2a 20 R;. }.. /*
0d40: 52 65 74 75 72 6e 20 6b 65 79 20 61 6e 64 20 69 Return key and i
0d50: 76 20 2a 2f 0a 20 20 20 20 69 66 20 28 63 69 70 v */. if (cip
0d60: 68 65 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 her == NULL) {..
0d70: 72 65 73 75 6c 74 4f 62 6a 20 3d 20 54 63 6c 5f resultObj = Tcl_
0d80: 4e 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a 28 NewByteArrayObj(
0d90: 74 6d 70 6b 65 79 69 76 2c 20 73 69 7a 65 29 3b tmpkeyiv, size);
0da0: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09 72 . } else {..r
0db0: 65 73 75 6c 74 4f 62 6a 20 3d 20 54 63 6c 5f 4e esultObj = Tcl_N
0dc0: 65 77 4c 69 73 74 4f 62 6a 28 30 2c 20 4e 55 4c ewListObj(0, NUL
0dd0: 4c 29 3b 0a 09 4c 41 50 50 45 4e 44 5f 42 41 52 L);..LAPPEND_BAR
0de0: 52 41 59 28 69 6e 74 65 72 70 2c 20 72 65 73 75 RAY(interp, resu
0df0: 6c 74 4f 62 6a 2c 20 22 6b 65 79 22 2c 20 74 6d ltObj, "key", tm
0e00: 70 6b 65 79 69 76 2c 20 69 6b 6c 65 6e 29 3b 0a pkeyiv, iklen);.
0e10: 09 4c 41 50 50 45 4e 44 5f 42 41 52 52 41 59 28 .LAPPEND_BARRAY(
0e20: 69 6e 74 65 72 70 2c 20 72 65 73 75 6c 74 4f 62 interp, resultOb
0e30: 6a 2c 20 22 69 76 22 2c 20 74 6d 70 6b 65 79 69 j, "iv", tmpkeyi
0e40: 76 2b 69 6b 6c 65 6e 2c 20 69 76 6c 65 6e 29 3b v+iklen, ivlen);
0e50: 0a 20 20 20 20 7d 0a 20 20 20 20 54 63 6c 5f 53 . }. Tcl_S
0e60: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 etObjResult(inte
0e70: 72 70 2c 20 72 65 73 75 6c 74 4f 62 6a 29 3b 0a rp, resultObj);.
0e80: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f return TCL_O
0e90: 4b 3b 0a 20 20 20 20 09 63 6c 69 65 6e 74 44 61 K;. .clientDa
0ea0: 74 61 20 3d 20 63 6c 69 65 6e 74 44 61 74 61 3b ta = clientData;
0eb0: 0a 7d 0a 0a 2f 2a 0a 20 2a 2d 2d 2d 2d 2d 2d 2d .}../*. *-------
0ec0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0ed0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0ee0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0ef0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 20 2a 0a ------------. *.
0f00: 20 2a 20 54 6c 73 5f 4b 65 79 43 6f 6d 6d 61 6e * Tls_KeyComman
0f10: 64 73 20 2d 2d 0a 20 2a 0a 20 2a 09 43 72 65 61 ds --. *. *.Crea
0f20: 74 65 20 6b 65 79 20 63 6f 6d 6d 61 6e 64 73 0a te key commands.
0f30: 20 2a 0a 20 2a 20 52 65 74 75 72 6e 73 3a 0a 20 *. * Returns:.
0f40: 2a 09 54 43 4c 5f 4f 4b 20 6f 72 20 54 43 4c 5f *.TCL_OK or TCL_
0f50: 45 52 52 4f 52 0a 20 2a 0a 20 2a 20 53 69 64 65 ERROR. *. * Side
0f60: 20 65 66 66 65 63 74 73 3a 0a 20 2a 09 43 72 65 effects:. *.Cre
0f70: 61 74 65 73 20 63 6f 6d 6d 61 6e 64 73 0a 20 2a ates commands. *
0f80: 0a 20 2a 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d . *-------------
0f90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0fa0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0fb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0fc0: 2d 2d 2d 2d 2d 2d 0a 20 2a 2f 0a 69 6e 74 20 54 ------. */.int T
0fd0: 6c 73 5f 4b 65 79 43 6f 6d 6d 61 6e 64 73 28 54 ls_KeyCommands(T
0fe0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 cl_Interp *inter
0ff0: 70 29 20 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65 p) {. Tcl_Cre
1000: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e ateObjCommand(in
1010: 74 65 72 70 2c 20 22 74 6c 73 3a 3a 64 65 72 69 terp, "tls::deri
1020: 76 65 5f 6b 65 79 22 2c 20 44 65 72 69 76 65 4b ve_key", DeriveK
1030: 65 79 2c 20 28 43 6c 69 65 6e 74 44 61 74 61 29 ey, (ClientData)
1040: 20 30 2c 20 28 54 63 6c 5f 43 6d 64 44 65 6c 65 0, (Tcl_CmdDele
1050: 74 65 50 72 6f 63 20 2a 29 20 4e 55 4c 4c 29 3b teProc *) NULL);
1060: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f . return TCL_
1070: 4f 4b 3b 0a 7d 0a 0a OK;.}..