int ora_descrypt(unsigned char **rs, unsigned char *result, int siz) { int i = 0; char lastkey[8]; des_key_schedule ks1; unsigned char key1[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; unsigned char ivec1[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned char *desresult; memset(ivec1, 0, sizeof(ivec1)); if ((desresult = malloc(siz)) == NULL) { hydra_report(stderr, "[ERROR] Can't allocate memory\n"); return 1; } des_key_sched((C_Block *) key1, ks1); des_ncbc_encrypt(result, desresult, siz, ks1, &ivec1, DES_ENCRYPT); for (i = 0; i < 8; i++) { lastkey[i] = desresult[siz - 8 + i]; } des_key_sched((C_Block *) lastkey, ks1); memset(desresult, 0, siz); memset(ivec1, 0, sizeof(ivec1)); des_ncbc_encrypt(result, desresult, siz, ks1, &ivec1, DES_ENCRYPT); if ((*rs = malloc(siz)) == NULL) { hydra_report(stderr, "[ERROR] Can't allocate memory\n"); free(desresult); return 1; } memcpy(*rs, desresult, siz); return 0; }
static void fb64_session(Session_Key *key, int server, struct fb *fbp) { if (!key || key->type != SK_DES) { if (encrypt_debug_mode) printf("Can't set krbdes's session key (%d != %d)\r\n", key ? key->type : -1, SK_DES); return; } memmove((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); des_key_sched((Block *)fbp->krbdes_key, fbp->krbdes_sched); /* * Now look to see if krbdes_start() was was waiting for * the key to show up. If so, go ahead an call it now * that we have the key. */ if (fbp->need_start) { fbp->need_start = 0; fb64_start(fbp, DIR_ENCRYPT, server); } }
static afs_int32 check_auth(struct packet *pkt, char *auth, int authLen, struct ktc_encryptionKey *key, char *name, char *inst, char *cell) { char *packet; des_key_schedule schedule; afs_int32 cksum; afs_int32 time_sec; int byteOrder = pkt->byteOrder; des_key_sched(ktc_to_cblock(key), schedule); des_pcbc_encrypt(auth, auth, authLen, schedule, ktc_to_cblockptr(key), DECRYPT); packet = auth; if (strcmp(packet, name) != 0) return KABADTICKET; packet += strlen(packet) + 1; if (strcmp(packet, inst) != 0) return KABADTICKET; packet += strlen(packet) + 1; if (strcmp(packet, cell) != 0) return KABADTICKET; packet += strlen(packet) + 1; getint(cksum); /* Comments in the original IBM source suggest this byte was/is "time_msec" */ packet++; getint(time_sec); if ((packet - auth) > authLen) return KABADTICKET; return 0; }
static int esp_des_schedule(const struct esp_algorithm *algo, struct secasvar *sav) { if (des_key_sched((des_cblock *)_KEYBUF(sav->key_enc), *(des_key_schedule *)sav->sched)) return EINVAL; else return 0; }
void fb64_stream_key(Block key, struct stinfo *stp) { memmove((void *)stp->str_ikey, (void *)key, sizeof(Block)); des_key_sched((Block *)key, stp->str_sched); memmove((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); stp->str_index = sizeof(Block); }
static afs_int32 create_cipher(char *cipher, int *cipherLen, struct ktc_encryptionKey *sessionKey, char *sname, char *sinst, Date start, Date end, afs_int32 kvno, char *ticket, int ticketLen, struct ktc_encryptionKey *key) { char *answer; int slen; unsigned char life = time_to_life(start, end); int len; des_key_schedule schedule; afs_int32 code; answer = cipher; len = sizeof(*sessionKey) + strlen(sname) + strlen(sinst) + strlen(lrealm) + 3 /*nulls */ + 3 + ticketLen + sizeof(Date); if (len > *cipherLen) return KAANSWERTOOLONG; if (ticketLen > 255) return KAANSWERTOOLONG; if (kvno > 255) return KAANSWERTOOLONG; memcpy(answer, sessionKey, sizeof(*sessionKey)); answer += sizeof(*sessionKey); putstr(sname); putstr(sinst); putstr(lrealm); *answer++ = life; *answer++ = (unsigned char)kvno; *answer++ = (unsigned char)ticketLen; memcpy(answer, ticket, ticketLen); answer += ticketLen; putint(start); if (krb_udp_debug) { printf("Printing ticket (%d) and date: ", ticketLen); ka_PrintBytes(ticket, ticketLen); ka_PrintBytes(answer - 4, 4); printf("\n"); } if ((code = des_key_sched(ktc_to_cblock(key), schedule))) printf("In KAAuthenticate: key_sched returned %d\n", code); des_pcbc_encrypt(cipher, cipher, len, schedule, ktc_to_cblockptr(key), ENCRYPT); *cipherLen = round_up_to_ebs(len); if (krb_udp_debug) { printf("Printing cipher (%d): ", *cipherLen); ka_PrintBytes(cipher, *cipherLen); printf("\n"); } return 0; }
/* * des_set_random_generator_seed: this routine is used to select a random * number stream. The stream that results is * totally determined by the passed in key. * (I.e., calling this routine again with the * same key allows repeating a sequence of * random numbers) * * Requires: key is a valid des key. I.e., has correct parity and is not a * weak des key. */ void des_set_random_generator_seed(des_cblock key) { int i; /* select the new stream: (note errors are not possible here...) */ LOCK_RANDOM; des_key_sched(key, random_sequence_key.d); /* "seek" to the start of the stream: */ for (i = 0; i < 8; i++) sequence_number[i] = 0; UNLOCK_RANDOM; }
caddr_t cgd_cipher_3des_init(int keylen, caddr_t key, int *blocksize) { struct c3des_privdata *cp; int error = 0; if (!blocksize) return NULL; if (*blocksize == -1) *blocksize = 64; if (keylen != (DES_KEY_SZ * 3 * 8) || *blocksize != 64) return NULL; cp = malloc(sizeof(*cp), M_DEVBUF, 0); if (!cp) return NULL; error = des_key_sched((des_cblock *)key, cp->cp_key1); error |= des_key_sched((des_cblock *)key + 1, cp->cp_key2); error |= des_key_sched((des_cblock *)key + 2, cp->cp_key3); if (error) { free(cp, M_DEVBUF); return NULL; } return (caddr_t)cp; }
static int esp_3des_schedule(const struct esp_algorithm *algo, struct secasvar *sav) { int error; des_key_schedule *p; int i; u_int8_t *k; p = (des_key_schedule *)sav->sched; k = _KEYBUF(sav->key_enc); for (i = 0; i < 3; i++) { error = des_key_sched((des_cblock *)(k + 8 * i), p[i]); if (error) return EINVAL; } return 0; }
static int mk_auth(struct krb4_data *d, KTEXT adat, char *service, char *host, int checksum) { int ret; CREDENTIALS cred; char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ]; strlcpy(sname, service, sizeof(sname)); strlcpy(inst, krb_get_phost(host), sizeof(inst)); strlcpy(realm, krb_realmofhost(host), sizeof(realm)); ret = krb_mk_req(adat, sname, inst, realm, checksum); if(ret) return ret; strlcpy(sname, service, sizeof(sname)); strlcpy(inst, krb_get_phost(host), sizeof(inst)); strlcpy(realm, krb_realmofhost(host), sizeof(realm)); ret = krb_get_cred(sname, inst, realm, &cred); memmove(&d->key, &cred.session, sizeof(des_cblock)); des_key_sched(&d->key, d->schedule); memset(&cred, 0, sizeof(cred)); return ret; }
void kauth(int argc, char **argv) { int ret; char buf[1024]; des_cblock key; des_key_schedule schedule; KTEXT_ST tkt, tktcopy; char *name; char *p; int overbose; char passwd[100]; int tmp; int save; if(argc > 2){ printf("usage: %s [principal]\n", argv[0]); code = -1; return; } if(argc == 2) name = argv[1]; else name = username; overbose = verbose; verbose = 0; save = set_command_prot(prot_private); ret = command("SITE KAUTH %s", name); if(ret != CONTINUE){ verbose = overbose; set_command_prot(save); code = -1; return; } verbose = overbose; p = strstr(reply_string, "T="); if(!p){ printf("Bad reply from server.\n"); set_command_prot(save); code = -1; return; } p += 2; tmp = base64_decode(p, &tkt.dat); if(tmp < 0){ printf("Failed to decode base64 in reply.\n"); set_command_prot(save); code = -1; return; } tkt.length = tmp; tktcopy.length = tkt.length; p = strstr(reply_string, "P="); if(!p){ printf("Bad reply from server.\n"); verbose = overbose; set_command_prot(save); code = -1; return; } name = p + 2; for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++); *p = 0; snprintf(buf, sizeof(buf), "Password for %s:", name); if (des_read_pw_string (passwd, sizeof(passwd)-1, buf, 0)) *passwd = '\0'; des_string_to_key (passwd, &key); des_key_sched(&key, schedule); des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat, tkt.length, schedule, &key, DES_DECRYPT); if (strcmp ((char*)tktcopy.dat + 8, KRB_TICKET_GRANTING_TICKET) != 0) { afs_string_to_key (passwd, krb_realmofhost(hostname), &key); des_key_sched (&key, schedule); des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat, tkt.length, schedule, &key, DES_DECRYPT); } memset(key, 0, sizeof(key)); memset(schedule, 0, sizeof(schedule)); memset(passwd, 0, sizeof(passwd)); if(base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) { printf("Out of memory base64-encoding.\n"); set_command_prot(save); code = -1; return; } memset (tktcopy.dat, 0, tktcopy.length); ret = command("SITE KAUTH %s %s", name, p); free(p); set_command_prot(save); if(ret != COMPLETE){ code = -1; return; } code = 0; }
static BOOL afs_createtoken(const char *username, const char *cell, DATA_BLOB *ticket, struct ClearToken *ct) { fstring clear_ticket; char *p = clear_ticket; uint32 len; uint32 now; struct afs_key key; des_key_schedule key_schedule; if (!secrets_init()) return False; if (!secrets_fetch_afs_key(cell, &key)) { DEBUG(1, ("Could not fetch AFS service key\n")); return False; } ct->AuthHandle = key.kvno; /* Build the ticket. This is going to be encrypted, so in our way we fill in ct while we still have the unencrypted form. */ p = clear_ticket; /* The byte-order */ *p = 1; p += 1; /* "Alice", the client username */ strncpy(p, username, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1); p += strlen(p)+1; strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1); p += strlen(p)+1; strncpy(p, cell, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1); p += strlen(p)+1; /* Alice's network layer address. At least Openafs-1.2.10 ignores this, so we fill in a dummy value here. */ SIVAL(p, 0, 0); p += 4; /* We need to create a session key */ generate_random_buffer(p, 8); /* Our client code needs the the key in the clear, it does not know the server-key ... */ memcpy(ct->HandShakeKey, p, 8); p += 8; /* This is a kerberos 4 life time. The life time is expressed * in units of 5 minute intervals up to 38400 seconds, after * that a table is used up to lifetime 0xBF. Values between * 0xC0 and 0xFF is undefined. 0xFF is defined to be the * infinite time that never expire. * * So here we cheat and use the infinite time */ *p = 255; p += 1; /* Ticket creation time */ now = time(NULL); SIVAL(p, 0, now); ct->BeginTimestamp = now; if(lp_afs_token_lifetime() == 0) ct->EndTimestamp = NEVERDATE; else ct->EndTimestamp = now + lp_afs_token_lifetime(); if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) { ct->BeginTimestamp += 1; /* Lifetime must be even */ } p += 4; /* And here comes Bob's name and instance, in this case the AFS server. */ strncpy(p, "afs", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1); p += strlen(p)+1; strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1); p += strlen(p)+1; /* And zero-pad to a multiple of 8 bytes */ len = PTR_DIFF(p, clear_ticket); if (len & 7) { uint32 extra_space = 8-(len & 7); memset(p, 0, extra_space); p+=extra_space; } len = PTR_DIFF(p, clear_ticket); des_key_sched((const_des_cblock *)key.key, key_schedule); des_pcbc_encrypt(clear_ticket, clear_ticket, len, key_schedule, (C_Block *)key.key, 1); ZERO_STRUCT(key); *ticket = data_blob(clear_ticket, len); return True; }
CURLcode Curl_krb_kauth(struct connectdata *conn) { des_cblock key; des_key_schedule schedule; KTEXT_ST tkt, tktcopy; char *name; char *p; char passwd[100]; size_t tmp; ssize_t nread; int save; CURLcode result; unsigned char *ptr; save = Curl_set_command_prot(conn, prot_private); result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user); if(result) return result; result = Curl_GetFTPResponse(&nread, conn, NULL); if(result) return result; if(conn->data->state.buffer[0] != '3'){ Curl_set_command_prot(conn, save); return CURLE_FTP_WEIRD_SERVER_REPLY; } p = strstr(conn->data->state.buffer, "T="); if(!p) { Curl_failf(conn->data, "Bad reply from server"); Curl_set_command_prot(conn, save); return CURLE_FTP_WEIRD_SERVER_REPLY; } p += 2; tmp = Curl_base64_decode(p, &ptr); if(tmp >= sizeof(tkt.dat)) { free(ptr); tmp=0; } if(!tmp || !ptr) { Curl_failf(conn->data, "Failed to decode base64 in reply"); Curl_set_command_prot(conn, save); return CURLE_FTP_WEIRD_SERVER_REPLY; } memcpy((char *)tkt.dat, ptr, tmp); free(ptr); tkt.length = tmp; tktcopy.length = tkt.length; p = strstr(conn->data->state.buffer, "P="); if(!p) { Curl_failf(conn->data, "Bad reply from server"); Curl_set_command_prot(conn, save); return CURLE_FTP_WEIRD_SERVER_REPLY; } name = p + 2; for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++); *p = 0; des_string_to_key (conn->passwd, &key); des_key_sched(&key, schedule); des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat, tkt.length, schedule, &key, DES_DECRYPT); if(strcmp ((char*)tktcopy.dat + 8, KRB_TICKET_GRANTING_TICKET) != 0) { afs_string_to_key(passwd, krb_realmofhost(conn->host.name), &key); des_key_sched(&key, schedule); des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat, tkt.length, schedule, &key, DES_DECRYPT); } memset(key, 0, sizeof(key)); memset(schedule, 0, sizeof(schedule)); memset(passwd, 0, sizeof(passwd)); if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p) < 1) { failf(conn->data, "Out of memory base64-encoding."); Curl_set_command_prot(conn, save); return CURLE_OUT_OF_MEMORY; } memset (tktcopy.dat, 0, tktcopy.length); result = Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p); free(p); if(result) return result; result = Curl_GetFTPResponse(&nread, conn, NULL); if(result) return result; Curl_set_command_prot(conn, save); return CURLE_OK; }
static int decrypt_tkt(char *user, char *instance, char *realm, char *arg, int (*key_proc)(char *, char *, char *, char *, C_Block), KTEXT *cipp) { MSG_DAT msg_data; /* Message data containing decrypted data */ KTEXT_ST auth; /* Authenticator */ AUTH_DAT auth_dat; /* Authentication data */ KTEXT cip = *cipp; MSG_DAT scip; int status = 0; des_cblock key; des_key_schedule sched; char phost[MAXHOSTNAMELEN + 1]; struct sockaddr_in caddr; /* client internet address */ struct sockaddr_in saddr; /* server internet address */ rkinitd_intkt_info *rii = (rkinitd_intkt_info *)arg; u_char enc_data[MAX_KTXT_LEN]; SBCLEAR(auth); SBCLEAR(auth_dat); SBCLEAR(scip); BCLEAR(enc_data); scip.app_data = enc_data; /* * Exchange with the client our response from the KDC (ticket encrypted * in user's private key) for the same ticket encrypted in our * (not yet known) session key. */ rpc_exchange_tkt(cip, &scip); /* * Get the authenticator */ SBCLEAR(auth); rpc_getauth(&auth, &caddr, &saddr); /* * Decode authenticator and extract session key. The first zero * means we don't care what host this comes from. This needs to * be done with euid of root so that /etc/srvtab can be read. */ BCLEAR(phost); this_phost(phost, sizeof(phost)); /* * This function has to use longjmp to return to the caller * because the kerberos library routine that calls it doesn't * pay attention to the return value it gives. That means that * if any of these routines failed, the error returned to the client * would be "password incorrect". */ status = krb_rd_req(&auth, KEY, phost, caddr.sin_addr.s_addr, &auth_dat, ""); if (status) { sprintf(errbuf, "krb_rd_req: %s", krb_err_txt[status]); rkinit_errmsg(errbuf); longjmp(rii->env, status); } memcpy(key, auth_dat.session, sizeof(key)); if (des_key_sched(key, sched)) { sprintf(errbuf, "Error in des_key_sched"); rkinit_errmsg(errbuf); longjmp(rii->env, RKINIT_DES); } /* Decrypt the data. */ if ((status = krb_rd_priv((u_char *)scip.app_data, scip.app_length, sched, key, &caddr, &saddr, &msg_data)) == KSUCCESS) { cip->length = msg_data.app_length; memcpy(cip->dat, msg_data.app_data, msg_data.app_length); cip->dat[cip->length] = 0; } else { sprintf(errbuf, "krb_rd_priv: %s", krb_err_txt[status]); rkinit_errmsg(errbuf); longjmp(rii->env, status); } if (setuid(user_id) < 0) { sprintf(errbuf, "Failure setting uid to %lu: %s\n", (unsigned long)user_id, strerror(errno)); rkinit_errmsg(errbuf); longjmp(rii->env, RKINIT_DAEMON); } return(KSUCCESS); }
void encrypt2(unsigned char *source, unsigned char *dest, unsigned char *Key3) { des_key_schedule ks1, ks2, ks3; des_cblock iv3; unsigned char tmpstr[64]; int err; // extern unsigned char cbc_key1[8]; // extern unsigned char cbc_key2[8]; // extern unsigned char cbc_key3[8]; // extern unsigned char cbc_user[8]; // extern unsigned char cbc_iv[8]; unsigned char * cbc_out; unsigned int cksum = 0; unsigned char *src; int num = 0; unsigned int i = 0; time_t timeStamp; struct tm *curTime; /* unsigned char key3[8]; memcpy(key3, cbc_key3, 8); */ src = (unsigned char *) calloc(strlen((char *) source) *4, sizeof(char)); strcpy((char *)src, (const char *) source); tzset(); timeStamp = time(NULL); curTime = localtime(&timeStamp); /* Okay, now we're going to prepend a timestamp onto our source string ** Which will be a total of 14 characters long (for removal later). */ sprintf(src, "%02d%02d%02d%02d%02d%04d%s", curTime->tm_sec, curTime->tm_min, curTime->tm_hour, curTime->tm_mday, curTime->tm_mon, curTime->tm_year, (const char *) source); for (i = 0; i < strlen((char *) src); i++) cksum += src[i]; cbc_out = (unsigned char *) calloc(strlen((const char *)src)*4, sizeof(char)); // Clear our destination string. dest[0] = '\0'; // Create our key schedules err = des_key_sched((C_Block *)cbc_key1, ks1); if (err) { printf("Key1 error %d\n", err); exit(-1); } err = des_key_sched((C_Block *)cbc_key2, ks2); if (err) { printf("Key2 error %d\n", err); exit(-1); } err = des_key_sched((C_Block *)Key3, ks3); if (err) { printf("Key3 error %d\n", err); exit(-1); } // Set up our iv3(?) block memcpy(iv3, cbc_iv, sizeof(cbc_iv)); des_ede3_cfb64_encrypt(src, cbc_out, (long )strlen((const char *)src), ks1, ks2, ks3, (C_Block *) iv3, &num, DES_ENCRYPT); for (i = 0; i < strlen((const char *)src); i++) { sprintf((char *) tmpstr, "%02x", cbc_out[i]); // printf("tmpstr = '%s'\n", (char *) tmpstr); // fflush(stdout); strcat((char *) dest, (const char *) tmpstr); } //fprintf(stderr, "bdes.c encrypt: Source = '%s'\n", (char *) source); //fprintf(stderr, "bdes.c encrypt: Target = '%s'\n", (char *) dest); // Now add the chesksum to the end. sprintf((char *) tmpstr, "%04x", cksum); strcat((char *) dest, (const char *) tmpstr); free(cbc_out); }
ULONG AnscCryptoDesMacDigest ( PVOID buffer, ULONG size, PANSC_CRYPTO_HASH hash, PANSC_CRYPTO_KEY key ) { #ifdef _ANSC_DES_USED_ ULONG i = 0; PUCHAR pAuthenticationData = NULL; PVOID pEncryptedData = NULL; ANSC_CRYPTO_IV iv = {0}; des_key_schedule keySchedule; /* * allocate memory to hold the encrypted data */ pEncryptedData = AnscAllocateMemory(size); if ( !pEncryptedData ) { AnscZeroMemory(hash->Value, hash->Length); return hash->Length; } /* * proceed des-cbc on the whole payload, but first we need to initialize the IV according to the draft, * IV should be filled by zeros. */ iv.Length = ANSC_DES_IV_SIZE; /* * retrieve a key schedule? */ des_key_sched ( (des_cblock*)key->Value[0], keySchedule ); /* * des-cbc */ des_cbc_encrypt ( (des_cblock*)buffer, /* input stream of data blocks */ (des_cblock*)pEncryptedData, /* output stream of data blocks */ size, /* total length of data stream */ keySchedule, /* key schedule */ (des_cblock*)iv.Value, /* initialization vector */ 1 /* indicate it's an encryption operation */ ); /* * use the last 8 bytes output as authentication data */ AnscCopyMemory ( hash->Value, (PVOID)((ULONG)pEncryptedData + size - ANSC_DES_BLOCK_SIZE), ANSC_DES_BLOCK_SIZE ); /* * let's make sure our output size is bigger than the requirement; otherwise, we should pad zeros to the end * of the hash result data */ if ( ANSC_DES_BLOCK_SIZE < hash->Length ) { AnscZeroMemory(&hash->Value[ANSC_DES_BLOCK_SIZE], hash->Length - ANSC_DES_BLOCK_SIZE); } /* * free the allocated memory */ AnscFreeMemory(pEncryptedData); #else AnscTrace("WARNING: DES digest is disabled!!!\n"); #endif /* * return control to caller */ return hash->Length; }
assert( dateTime == NULL || isReadPtr( dateTime, X917_KEYSIZE ) ); /* Precondition: the key and seed aren't being taken from the same location */ REQUIRES( sanityCheck( randomInfo ) ); REQUIRES( memcmp( key, state, X917_POOLSIZE ) ); /* Remember that we're about to reset the generator state */ randomInfo->x917Inited = FALSE; /* Schedule the DES keys. Rather than performing the third key schedule we just copy the first scheduled key into the third one, since it's the same key in EDE mode */ des_set_odd_parity( ( C_Block * ) key ); des_set_odd_parity( ( C_Block * ) ( key + bitsToBytes( 64 ) ) ); desStatus = des_key_sched( ( des_cblock * ) key, des3Key->desKey1 ); if( desStatus == 0 ) { desStatus = des_key_sched( ( des_cblock * ) \ ( key + bitsToBytes( 64 ) ), des3Key->desKey2 ); } memcpy( des3Key->desKey3, des3Key->desKey1, DES_KEYSIZE ); if( desStatus ) { /* There was a problem initialising the keys, don't try and go any further */ ENSURES( randomInfo->x917Inited == FALSE ); return( CRYPT_ERROR_RANDOM ); }
_SCAPI_NOT_CONFIGURED #endif /* USE_INTERNAL_MD5 */ /*******************************************************************-o-****** * sc_encrypt * * Parameters: * privtype Type of privacy cryptographic transform. * *key Key bits for crypting. * keylen Length of key (buffer) in bytes. * *iv IV bits for crypting. * ivlen Length of iv (buffer) in bytes. * *plaintext Plaintext to crypt. * ptlen Length of plaintext. * *ciphertext Ciphertext to crypt. * *ctlen Length of ciphertext. * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported. * SNMPERR_SC_GENERAL_FAILURE Any other error * * * Encrypt plaintext into ciphertext using key and iv. * * ctlen contains actual number of crypted bytes in ciphertext upon * successful return. */ int sc_encrypt( oid *privtype, size_t privtypelen, u_char *key, u_int keylen, u_char *iv, u_int ivlen, u_char *plaintext, u_int ptlen, u_char *ciphertext, size_t *ctlen) #if defined(USE_OPENSSL) { int rval = SNMPERR_SUCCESS; u_int transform, properlength, properlength_iv; u_char pad_block[32]; /* bigger than anything I need */ u_char my_iv[32]; /* ditto */ int pad, plast, pad_size; des_key_schedule key_sch; des_cblock key_struct; DEBUGTRACE; /* * Sanity check. */ #if !defined(SCAPI_AUTHPRIV) return SNMPERR_SC_NOT_CONFIGURED; #endif if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ctlen || (keylen<=0) || (ivlen<=0) || (ptlen<=0) || (*ctlen<=0) || (privtypelen != USM_LENGTH_OID_TRANSFORM) ) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } else if ( ptlen >= *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } #ifdef SNMP_TESTING_CODE { char buf[SNMP_MAXBUF]; sprint_hexstring(buf, iv, ivlen); DEBUGMSGTL(("scapi", "encrypt: IV: %s/ ", buf)); sprint_hexstring(buf, key, keylen); DEBUGMSG(("scapi","%s\n", buf)); sprint_hexstring(buf, plaintext, 16); DEBUGMSGTL(("scapi","encrypt: string: %s\n", buf)); } #endif /* SNMP_TESTING_CODE */ /* * Determine privacy transform. */ if ( ISTRANSFORM(privtype, DESPriv) ) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV); pad_size = properlength; } else { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } if ( (keylen<properlength) || (ivlen<properlength_iv) ) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } else if ( (keylen<properlength) || (ivlen<properlength_iv) ) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } /* now calculate the padding needed */ pad = pad_size - (ptlen % pad_size); if (ptlen + pad > *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */ } memset(pad_block, 0, sizeof(pad_block)); plast = (int) ptlen - (pad_size - pad); if (pad > 0) /* copy data into pad block if needed */ memcpy( pad_block, plaintext + plast, pad_size - pad); memset(&pad_block[pad_size-pad], pad, pad); /* filling in padblock */ memset(my_iv, 0, sizeof(my_iv)); if ( ISTRANSFORM(privtype, DESPriv) ) { memcpy(key_struct, key, sizeof(key_struct)); (void) des_key_sched(&key_struct, key_sch); memcpy(my_iv, iv, ivlen); /* encrypt the data */ des_ncbc_encrypt(plaintext, ciphertext, plast, key_sch, (des_cblock *) &my_iv, DES_ENCRYPT); /* then encrypt the pad block */ des_ncbc_encrypt(pad_block, ciphertext+plast, pad_size, key_sch, (des_cblock *)&my_iv, DES_ENCRYPT); *ctlen = plast + pad_size; } sc_encrypt_quit: /* clear memory just in case */ memset(my_iv, 0, sizeof(my_iv)); memset(pad_block, 0, sizeof(pad_block)); memset(key_struct, 0, sizeof(key_struct)); memset(key_sch, 0, sizeof(key_sch)); return rval; } /* end sc_encrypt() */
static int try_krb4_authentication(void) { KTEXT_ST auth; /* Kerberos data */ char *reply; char inst[INST_SZ]; char *realm; CREDENTIALS cred; int r, type; socklen_t slen; Key_schedule schedule; u_long checksum, cksum; MSG_DAT msg_data; struct sockaddr_in local, foreign; struct stat st; /* Don't do anything if we don't have any tickets. */ if (stat(tkt_string(), &st) < 0) return 0; strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)), INST_SZ); realm = (char *)krb_realmofhost(get_canonical_hostname(1)); if (!realm) { debug("Kerberos v4: no realm for %s", get_canonical_hostname(1)); return 0; } /* This can really be anything. */ checksum = (u_long)getpid(); r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); if (r != KSUCCESS) { debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]); return 0; } /* Get session key to decrypt the server's reply with. */ r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); if (r != KSUCCESS) { debug("get_cred failed: %s", krb_err_txt[r]); return 0; } des_key_sched((des_cblock *) cred.session, schedule); /* Send authentication info to server. */ packet_start(SSH_CMSG_AUTH_KERBEROS); packet_put_string((char *) auth.dat, auth.length); packet_send(); packet_write_wait(); /* Zero the buffer. */ (void) memset(auth.dat, 0, MAX_KTXT_LEN); slen = sizeof(local); memset(&local, 0, sizeof(local)); if (getsockname(packet_get_connection_in(), (struct sockaddr *)&local, &slen) < 0) debug("getsockname failed: %s", strerror(errno)); slen = sizeof(foreign); memset(&foreign, 0, sizeof(foreign)); if (getpeername(packet_get_connection_in(), (struct sockaddr *)&foreign, &slen) < 0) { debug("getpeername failed: %s", strerror(errno)); cleanup_exit(255); } /* Get server reply. */ type = packet_read(); switch (type) { case SSH_SMSG_FAILURE: /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ debug("Kerberos v4 authentication failed."); return 0; break; case SSH_SMSG_AUTH_KERBEROS_RESPONSE: /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ debug("Kerberos v4 authentication accepted."); /* Get server's response. */ reply = packet_get_string((u_int *) &auth.length); if (auth.length >= MAX_KTXT_LEN) fatal("Kerberos v4: Malformed response from server"); memcpy(auth.dat, reply, auth.length); free(reply); packet_check_eom(); /* * If his response isn't properly encrypted with the session * key, and the decrypted checksum fails to match, he's * bogus. Bail out. */ r = krb_rd_priv(auth.dat, auth.length, (void *)schedule, &cred.session, &foreign, &local, &msg_data); if (r != KSUCCESS) { debug("Kerberos v4 krb_rd_priv failed: %s", krb_err_txt[r]); packet_disconnect("Kerberos v4 challenge failed!"); } /* Fetch the (incremented) checksum that we supplied in the request. */ memcpy((char *)&cksum, (char *)msg_data.app_data, sizeof(cksum)); cksum = ntohl(cksum); /* If it matches, we're golden. */ if (cksum == checksum + 1) { debug("Kerberos v4 challenge successful."); return 1; } else packet_disconnect("Kerberos v4 challenge failed!"); break; default: packet_disconnect("Protocol error on Kerberos v4 response: %d", type); } return 0; }
int get_file(int conn, char *pathname, int file_size, int checksum, int mode, int encrypt) { int fd, n_written, code; int found_checksum; char buf[BUFSIZ]; memset(buf, '\0', sizeof(buf)); if (!have_authorization) { send_int(conn, MR_PERM); return 1; } if (setuid(uid) < 0) { com_err(whoami, errno, "Unable to setuid to %d\n", uid); exit(1); } /* unlink old file */ if (!config_lookup("noclobber")) unlink(pathname); /* open file descriptor */ fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, mode); if (fd == -1) { code = errno; com_err(whoami, errno, "creating file %s (get_file)", pathname); send_int(conn, code); return 1; } /* check to see if we've got the disk space */ n_written = 0; while (n_written < file_size) { int n_wrote; n_wrote = write(fd, buf, sizeof(buf)); if (n_wrote == -1) { code = errno; com_err(whoami, code, "verifying free disk space for %s (get_file)", pathname); send_int(conn, code); /* do all we can to free the space */ unlink(pathname); ftruncate(fd, 0); close(fd); return 1; } n_written += n_wrote; } lseek(fd, 0, SEEK_SET); send_ok(conn); if (encrypt) { #ifdef HAVE_KRB4 des_key_sched(session, sched); memcpy(ivec, session, sizeof(ivec)); #else /* The session key only gets stored if auth happens in krb4 to begin with. If you don't have krb4, you can't possibly be coming up with a valid session key. */ return MR_NO_KRB4; #endif } n_written = 0; while (n_written < file_size) { int n_got = get_block(conn, fd, file_size - n_written, encrypt); if (n_got == -1) { /* get_block has already printed a message */ unlink(pathname); return 1; } n_written += n_got; if (n_written != file_size) send_ok(conn); } fsync(fd); ftruncate(fd, file_size); fsync(fd); close(fd); /* validate checksum */ found_checksum = checksum_file(pathname); if (checksum != found_checksum) { code = MR_MISSINGFILE; com_err(whoami, code, ": expected = %d, found = %d", checksum, found_checksum); send_int(conn, code); return 1; } send_ok(conn); return 0; }
void encrypt_string(unsigned char *source, unsigned char *dest, int UseUser) { des_key_schedule ks1, ks2, ks3; des_cblock iv3; unsigned char tmpstr[64]; int err; // extern unsigned char cbc_key1[8]; // extern unsigned char cbc_key2[8]; // extern unsigned char cbc_key3[8]; // extern unsigned char cbc_user[8]; // extern unsigned char cbc_iv[8]; unsigned char * cbc_out; unsigned int cksum = 0; unsigned char *src; int num = 0; unsigned int i = 0; unsigned char key3[8]; if (UseUser) { memcpy(key3, cbc_user, 8); } else { memcpy(key3, cbc_key3, 8); } src = (char *) calloc(strlen((char *) source) * 4, sizeof(char)); strcpy((char *)src, (const char *) source); // The source must be evenly divisible by 16... // printf("Making the source divisible by 16...\n"); // fflush(stdout); /* while (strlen((const char *)src) % 16) { // printf("strlen(src) = %d\n", strlen((const char *)src)); // fflush(stdout); src[strlen((char *)src)+1] = '\0'; src[strlen((char *)src)] = ' '; } // printf("Done making the source divisible by 8...\n"); */ for (i = 0; i < strlen((char *) src); i++) cksum += src[i]; cbc_out = (unsigned char *) calloc(strlen((const char *)src)* 4, sizeof(char)); // Clear our destination string. dest[0] = '\0'; // Create our key schedules err = des_key_sched((C_Block *)cbc_key1, ks1); if (err) { printf("Key1 error %d\n", err); exit(-1); } err = des_key_sched((C_Block *)cbc_key2, ks2); if (err) { printf("Key2 error %d\n", err); exit(-1); } err = des_key_sched((C_Block *)key3, ks3); if (err) { printf("Key3 error %d\n", err); exit(-1); } // Set up our iv3(?) block memcpy(iv3, cbc_iv, sizeof(cbc_iv)); des_ede3_cfb64_encrypt(src, cbc_out, (long )strlen((const char *)src), ks1, ks2, ks3, (C_Block *) iv3, &num, DES_ENCRYPT); for (i = 0; i < strlen((const char *)src); i++) { sprintf((char *) tmpstr, "%02x", cbc_out[i]); // printf("tmpstr = '%s'\n", (char *) tmpstr); // fflush(stdout); strcat((char *) dest, (const char *) tmpstr); } // Now add the chesksum to the end. sprintf((char *) tmpstr, "%04x", cksum); strcat((char *) dest, (const char *) tmpstr); free(cbc_out); }
int decrypt2(unsigned char *source, unsigned char *dest, unsigned char *Key3) { des_key_schedule ks1, ks2, ks3; des_cblock iv3; char tmpstr[64]; int err; unsigned int cksum = 0; unsigned int cksum2 = 0; unsigned char ckstr[20]; unsigned char * cbc_in; unsigned char * src; unsigned char * dst; unsigned char * dst2; int num = 0; int RetVal = 0; int j = 0; unsigned int i = 0; /* unsigned char key3[8]; memcpy(key3, cbc_key3, 8); */ src = (unsigned char *) calloc(strlen((char *) source) *4, sizeof(char)); dst = (unsigned char *) calloc(strlen((char *) source) *4, sizeof(char)); strcpy((char *)src, (const char *) source); memset(ckstr, 0, 16); // First things first. If strlen(src) - 4 / 8 != 0, this is not // a valid source... /* if ((strlen((const char *) src) - 4) % 16) { // Invalid source string... return(-1); } */ // Get our checksum out of the src. j = 0; for (i = strlen((const char *) src) - 4; i < strlen((const char *) src); i++) { ckstr[j++] = src[i]; } src[strlen((const char *)src)-4] = '\0'; cksum = strtol((const char *)ckstr, (char **)NULL, 16); // printf("cksum = 0x%s %d\n", ckstr, cksum); // fflush(stdout); cbc_in = (unsigned char *) calloc(strlen((char *)src)*4, sizeof(char)); // Clear our destination string. dest[0] = '\0'; // Create our key schedules err = des_key_sched((C_Block *)cbc_key1, ks1); if (err) { printf("Key1 error %d\n", err); exit(-1); } err = des_key_sched((C_Block *)cbc_key2, ks2); if (err) { printf("Key2 error %d\n", err); exit(-1); } err = des_key_sched((C_Block *)Key3, ks3); if (err) { printf("Key3 error %d\n", err); exit(-1); } // Set up our iv3(?) block memcpy(iv3, cbc_iv, sizeof(cbc_iv)); // Make our source something usable. j = 0; for (i = 0; i < strlen((char *)src); i += 2) { sprintf(tmpstr, "%c%c", src[i], src[i+1]); cbc_in[j++] = strtol(tmpstr, (char **)NULL, 16); } des_ede3_cfb64_encrypt(cbc_in, dst, (long )strlen((char *)src)/2, ks1, ks2, ks3, (C_Block *) iv3, &num, DES_DECRYPT); // Before we strip the trailing pad from the string, get the checksum for (i = 0; i < strlen((char *) dest); i++) cksum2 += dest[i]; // printf("cksum2 = %d\n", cksum2); // Now, strip all of the trailing pad from the string. /* while (dst[strlen((const char *)dst)-1] == ' ') { dst[strlen((const char *)dst)-1] = '\0'; } */ dst2 = dst; dst2 += 14; strcpy((char *)dest, (char *)dst2); //fprintf(stderr, "bdes.c decrypt: Source = '%s'\n", (char *) source); //fprintf(stderr, "bdes.c decrypt: Target = '%s'\n", (char *) dest); //fprintf(stderr, "bdes.c decrypt: Working= '%s'\n", (char *) dst); free(cbc_in); free(src); free(dst); // CkSum checks don't work yet... // if (cksum != cksum2) RetVal = -1; return(RetVal); }
int test_main(void) { int i,j,err=0; des_cblock in, out, outin, iv3; des_key_schedule ks,ks2,ks3; des_cblock cbc_in[5]; des_cblock cbc_out[5]; DES_LONG cs; unsigned char qret[4][4],cret[8]; DES_LONG lqret[4]; int num; char *str; printf("Doing ecb\n"); for (i=0; i<NUM_TESTS; i++) { if ((j=des_key_sched(&key_data[i], ks)) != 0) { printf("Key error %2d:%d\n",i+1,j); err=1; } memcpy(in,plain_data[i],8); memset(out,0,8); memset(outin,0,8); des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT); des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT); if (memcmp(out,cipher_data[i],8) != 0) { printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]), pt(out)); err=1; } if (memcmp(in,outin,8) != 0) { printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); err=1; } } #ifndef LIBDES_LIT printf("Doing ede ecb\n"); for (i=0; i<(NUM_TESTS-1); i++) { if ((j=des_key_sched(&key_data[i], ks)) != 0) { err=1; printf("Key error %2d:%d\n",i+1,j); } if ((j=des_key_sched(&key_data[i+1],ks2)) != 0) { printf("Key error %2d:%d\n",i+2,j); err=1; } if ((j=des_key_sched(&key_data[i+2],ks3)) != 0) { printf("Key error %2d:%d\n",i+3,j); err=1; } memcpy(in,plain_data[i],8); memset(out,0,8); memset(outin,0,8); des_ecb2_encrypt(&in, &out, ks, ks2, DES_ENCRYPT); des_ecb2_encrypt(&out, &outin, ks, ks2, DES_DECRYPT); if (memcmp(out,cipher_ecb2[i],8) != 0) { printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]), pt(out)); err=1; } if (memcmp(in,outin,8) != 0) { printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); err=1; } } #endif printf("Doing cbc\n"); if ((j=des_key_sched(&cbc_key, ks)) != 0) { printf("Key error %d\n",j); err=1; } memset(cbc_out,0,sizeof(cbc_data)); memset(cbc_in,0,sizeof(cbc_data)); memcpy(iv3,cbc_iv,sizeof(cbc_iv)); des_ncbc_encrypt(cbc_data, cbc_out, sizeof(cbc_data), ks, &iv3, DES_ENCRYPT); if (memcmp(cbc_out,cbc_ok,32) != 0) printf("cbc_encrypt encrypt error\n"); memcpy(iv3,cbc_iv,sizeof(cbc_iv)); des_ncbc_encrypt(cbc_out, cbc_in, sizeof(cbc_data),ks, &iv3,DES_DECRYPT); if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0) { printf("cbc_encrypt decrypt error\n"); err=1; } #ifndef LIBDES_LIT #if 0 printf("Doing desx cbc\n"); if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) { printf("Key error %d\n",j); err=1; } memset(cbc_out,0,sizeof(cbc_data)); memset(cbc_in,0,sizeof(cbc_data)); memcpy(iv3,cbc_iv,sizeof(cbc_iv)); des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, sizeof(cbc_data), ks, (C_Block *)iv3, (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT); if (memcmp(cbc_out,xcbc_ok,32) != 0) { printf("des_xcbc_encrypt encrypt error\n"); } memcpy(iv3,cbc_iv,sizeof(cbc_iv)); des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, sizeof(cbc_data), ks, (C_Block *)iv3, (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT); if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0) { printf("des_xcbc_encrypt decrypt error\n"); err=1; } #endif #endif /* LIBDES_LIT */ printf("Doing ede cbc\n"); if ((j=des_key_sched(&cbc_key,ks)) != 0) { printf("Key error %d\n",j); err=1; } if ((j=des_key_sched(&cbc2_key,ks2)) != 0) { printf("Key error %d\n",j); err=1; } if ((j=des_key_sched(&cbc3_key,ks3)) != 0) { printf("Key error %d\n",j); err=1; } memset(cbc_out,0,sizeof(cbc_data)); memset(cbc_in,0,sizeof(cbc_data)); i=sizeof(cbc_data); /* i=((i+7)/8)*8; */ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); des_ede3_cbc_encrypt( cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, DES_ENCRYPT); des_ede3_cbc_encrypt( &cbc_data[2], &cbc_out[2], (long)i-16, ks, ks2, ks3, &iv3, DES_ENCRYPT); if (memcmp(cbc_out,cbc3_ok, sizeof(cbc_data)) != 0) { printf("des_ede3_cbc_encrypt encrypt error\n"); err=1; } memcpy(iv3,cbc_iv,sizeof(cbc_iv)); des_ede3_cbc_encrypt(cbc_out, cbc_in, (long)i, ks, ks2, ks3, &iv3, DES_DECRYPT); if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0) { printf("des_ede3_cbc_encrypt decrypt error\n"); err=1; } #ifndef LIBDES_LIT #if 0 printf("Doing pcbc\n"); if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) { printf("Key error %d\n",j); err=1; } memset(cbc_out,0,sizeof(cbc_data)); memset(cbc_in,0,sizeof(cbc_data)); des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, sizeof(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT); if (memcmp(cbc_out,pcbc_ok,32) != 0) { printf("pcbc_encrypt encrypt error\n"); err=1; } des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, sizeof(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT); if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0) { printf("pcbc_encrypt decrypt error\n"); err=1; } printf("Doing "); printf("cfb8 "); err+=cfb_test(8,cfb_cipher8); printf("cfb16 "); err+=cfb_test(16,cfb_cipher16); printf("cfb32 "); err+=cfb_test(32,cfb_cipher32); printf("cfb48 "); err+=cfb_test(48,cfb_cipher48); printf("cfb64 "); err+=cfb_test(64,cfb_cipher64); printf("cfb64() "); err+=cfb64_test(cfb_cipher64); memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); for (i=0; i<sizeof(plain); i++) des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]), 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT); if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0) { printf("cfb_encrypt small encrypt error\n"); err=1; } memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); for (i=0; i<sizeof(plain); i++) des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]), 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT); if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) { printf("cfb_encrypt small decrypt error\n"); err=1; } printf("ede_cfb64() "); err+=ede_cfb64_test(cfb_cipher64); printf("done\n"); printf("Doing ofb\n"); des_key_sched((C_Block *)ofb_key,ks); memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks, (C_Block *)ofb_tmp); if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) { printf("ofb_encrypt encrypt error\n"); porintf("%02X %02X %02X %02X %02X %02X %02X %02X\n", ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3], ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]); printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3], ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]); err=1; } memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks, (C_Block *)ofb_tmp); if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) { printf("ofb_encrypt decrypt error\n"); printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3], ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]); printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", plain[8+0], plain[8+1], plain[8+2], plain[8+3], plain[8+4], plain[8+5], plain[8+6], plain[8+7]); err=1; } printf("Doing ofb64\n"); des_key_sched((C_Block *)ofb_key,ks); memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); memset(ofb_buf1,0,sizeof(ofb_buf1)); memset(ofb_buf2,0,sizeof(ofb_buf1)); num=0; for (i=0; i<sizeof(plain); i++) { des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks, (C_Block *)ofb_tmp,&num); } if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) { printf("ofb64_encrypt encrypt error\n"); err=1; } memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); num=0; des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks, (C_Block *)ofb_tmp,&num); if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) { printf("ofb64_encrypt decrypt error\n"); err=1; } printf("Doing ede_ofb64\n"); des_key_sched((C_Block *)ofb_key,ks); memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); memset(ofb_buf1,0,sizeof(ofb_buf1)); memset(ofb_buf2,0,sizeof(ofb_buf1)); num=0; for (i=0; i<sizeof(plain); i++) { des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks, (C_Block *)ofb_tmp,&num); } if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) { printf("ede_ofb64_encrypt encrypt error\n"); err=1; } memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); num=0; des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks, ks,ks,(C_Block *)ofb_tmp,&num); if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) { printf("ede_ofb64_encrypt decrypt error\n"); err=1; } #endif printf("Doing cbc_cksum\n"); des_key_sched(&cbc_key,ks); cs=des_cbc_cksum(cbc_data[0], &cret, sizeof(cbc_data), ks, &cbc_iv); if (cs != cbc_cksum_ret) { printf("bad return value (%08lX), should be %08lX\n", (unsigned long)cs,(unsigned long)cbc_cksum_ret); err=1; } if (memcmp(cret,cbc_cksum_data,8) != 0) { printf("bad cbc_cksum block returned\n"); err=1; } #if 0 printf("Doing quad_cksum\n"); cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret, sizeof(cbc_data),2,(C_Block *)cbc_iv); for (i=0; i<4; i++) { lqret[i]=0; memcpy(&(lqret[i]),&(qret[i][0]),4); } { /* Big-endian fix */ static DES_LONG l=1; static unsigned char *c=(unsigned char *)&l; DES_LONG ll; if (!c[0]) { ll=lqret[0]^lqret[3]; lqret[0]^=ll; lqret[3]^=ll; ll=lqret[1]^lqret[2]; lqret[1]^=ll; lqret[2]^=ll; } } if (cs != 0x70d7a63aL) { printf("quad_cksum error, ret %08lx should be 70d7a63a\n", (unsigned long)cs); err=1; } if (lqret[0] != 0x327eba8dL) { printf("quad_cksum error, out[0] %08lx is not %08lx\n", (unsigned long)lqret[0],0x327eba8dL); err=1; } if (lqret[1] != 0x201a49ccL) { printf("quad_cksum error, out[1] %08lx is not %08lx\n", (unsigned long)lqret[1],0x201a49ccL); err=1; } if (lqret[2] != 0x70d7a63aL) { printf("quad_cksum error, out[2] %08lx is not %08lx\n", (unsigned long)lqret[2],0x70d7a63aL); err=1; } if (lqret[3] != 0x501c2c26L) { printf("quad_cksum error, out[3] %08lx is not %08lx\n", (unsigned long)lqret[3],0x501c2c26L); err=1; } #endif #endif /* LIBDES_LIT */ #if 0 printf("input word alignment test"); for (i=0; i<4; i++) { printf(" %d",i); des_ncbc_encrypt( (des_cblock *) &(cbc_out[i]), (des_cblock *) cbc_in, sizeof(cbc_data), ks, &cbc_iv, DES_ENCRYPT); } printf("\noutput word alignment test"); for (i=0; i<4; i++) { printf(" %d",i); des_ncbc_encrypt( (des_cblock *) cbc_out, (des_cblock *) &(cbc_in[i]), sizeof(cbc_data), ks, &cbc_iv, DES_ENCRYPT); } printf("\n"); printf("fast crypt test "); str=crypt("testing","ef"); if (strcmp("efGnQx2725bI2",str) != 0) { printf("fast crypt error, %s should be efGnQx2725bI2\n",str); err=1; } str=crypt("bca76;23","yA"); if (strcmp("yA1Rp/1hZXIJk",str) != 0) { printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str); err=1; } printf("\n"); #endif exit(err); return(0); }
int auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply) { AUTH_DAT adat = {0}; Key_schedule schedule; struct sockaddr_in local, foreign; char instance[INST_SZ]; socklen_t slen; u_int cksum; int r, s; s = packet_get_connection_in(); slen = sizeof(local); memset(&local, 0, sizeof(local)); if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) debug("getsockname failed: %.100s", strerror(errno)); slen = sizeof(foreign); memset(&foreign, 0, sizeof(foreign)); if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); fatal_cleanup(); } instance[0] = '*'; instance[1] = 0; /* Get the encrypted request, challenge, and session key. */ if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]); return (0); } des_key_sched((des_cblock *) adat.session, schedule); *client = xmalloc(MAX_K_NAME_SZ); (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, *adat.pinst ? "." : "", adat.pinst, adat.prealm); /* Check ~/.klogin authorization now. */ if (kuserok(&adat, authctxt->user) != KSUCCESS) { log("Kerberos v4 .klogin authorization failed for %s to " "account %s", *client, authctxt->user); xfree(*client); *client = NULL; return (0); } /* Increment the checksum, and return it encrypted with the session key. */ cksum = adat.checksum + 1; cksum = htonl(cksum); /* If we can't successfully encrypt the checksum, we send back an empty message, admitting our failure. */ if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1, schedule, &adat.session, &local, &foreign)) < 0) { debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]); reply->dat[0] = 0; reply->length = 0; } else reply->length = r; /* Clear session key. */ memset(&adat.session, 0, sizeof(&adat.session)); return (1); }
/* * Function: K4 parse authentication reply command * * Parameters: * ks - kstream to send abort message to. * * parsedat - the sub-command data. * * end_sub - index of the character in the 'parsedat' array which * is the last byte in a sub-negotiation * * Returns: Kerberos error code. */ static int k4_auth_reply(kstream ks, unsigned char *parsedat, int end_sub) { time_t t; int x; char buf[512]; int i; des_cblock session_key; des_key_schedule sched; static des_cblock challenge; if (end_sub < 4) return KFAILURE; if (parsedat[2] != KERBEROS_V4) return KFAILURE; if (parsedat[4] == KRB_REJECT) { buf[0] = 0; for (i = 5; i <= end_sub; i++) { if (parsedat[i] == IAC) break; buf[i-5] = parsedat[i]; buf[i-4] = 0; } if (!buf[0]) strcpy(buf, "Authentication rejected by remote machine!"); MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION); return KFAILURE; } if (parsedat[4] == KRB_ACCEPT) { if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) return KSUCCESS; if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) return KFAILURE; des_key_sched(cred.session, sched); t = time(NULL); memcpy(challenge, &t, 4); memcpy(&challenge[4], &t, 4); des_ecb_encrypt(&challenge, &session_key, sched, 1); /* * Increment the challenge by 1, and encrypt it for * later comparison. */ for (i = 7; i >= 0; --i) { x = (unsigned int)challenge[i] + 1; challenge[i] = x; /* ignore overflow */ if (x < 256) /* if no overflow, all done */ break; } des_ecb_encrypt(&challenge, &challenge, sched, 1); wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, KRB_CHALLENGE); memcpy(&buf[7], session_key, 8); wsprintf(&buf[15], "%c%c", IAC, SE); TelnetSend(ks, (LPSTR)buf, 17, 0); return KSUCCESS; } if (parsedat[4] == KRB_RESPONSE) { if (end_sub < 12) return KFAILURE; if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) { MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!", NULL, MB_OK | MB_ICONEXCLAMATION); return KFAILURE; } return KSUCCESS; } return KFAILURE; }
static int kerberos4_send(char *name, Authenticator *ap) { KTEXT_ST auth; char instance[INST_SZ]; char *realm; CREDENTIALS cred; int r; printf("[ Trying %s ... ]\r\n", name); if (!UserNameRequested) { if (auth_debug_mode) { printf("Kerberos V4: no user name supplied\r\n"); } return(0); } memset(instance, 0, sizeof(instance)); if ((realm = krb_get_phost(RemoteHostName))) strncpy(instance, realm, sizeof(instance)); instance[sizeof(instance)-1] = '\0'; realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName); if (!realm) { printf("Kerberos V4: no realm for %s\r\n", RemoteHostName); return(0); } r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L); if (r) { printf("mk_req failed: %s\r\n", krb_get_err_text(r)); return(0); } r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); if (r) { printf("get_cred failed: %s\r\n", krb_get_err_text(r)); return(0); } if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { if (auth_debug_mode) printf("Not enough room for user name\r\n"); return(0); } if (auth_debug_mode) printf("Sent %d bytes of authentication data\r\n", auth.length); if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) { if (auth_debug_mode) printf("Not enough room for authentication data\r\n"); return(0); } #ifdef ENCRYPTION /* create challenge */ if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) { int i; des_key_sched(&cred.session, sched); des_init_random_number_generator(&cred.session); des_new_random_key(&session_key); des_ecb_encrypt(&session_key, &session_key, sched, 0); des_ecb_encrypt(&session_key, &challenge, sched, 0); /* old code Some CERT Advisory thinks this is a bad thing... des_init_random_number_generator(&cred.session); des_new_random_key(&challenge); des_ecb_encrypt(&challenge, &session_key, sched, 1); */ /* * Increment the challenge by 1, and encrypt it for * later comparison. */ for (i = 7; i >= 0; --i) if(++challenge[i] != 0) /* No carry! */ break; des_ecb_encrypt(&challenge, &challenge, sched, 1); } #endif if (auth_debug_mode) { printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); printf("Sent Kerberos V4 credentials to server\r\n"); } return(1); }
void kerberos4_is(Authenticator *ap, unsigned char *data, int cnt) { struct sockaddr_in addr; char realm[REALM_SZ]; char instance[INST_SZ]; int r; int addr_len; if (cnt-- < 1) return; switch (*data++) { case KRB_AUTH: if (krb_get_lrealm(realm, 1) != KSUCCESS) { Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1); auth_finished(ap, AUTH_REJECT); if (auth_debug_mode) printf("No local realm\r\n"); return; } memmove(auth.dat, data, auth.length = cnt); if (auth_debug_mode) { printf("Got %d bytes of authentication data\r\n", cnt); printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); } k_getsockinst(0, instance, sizeof(instance)); addr_len = sizeof(addr); if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) { if(auth_debug_mode) printf("getpeername failed\r\n"); Data(ap, KRB_REJECT, "getpeername failed", -1); auth_finished(ap, AUTH_REJECT); return; } r = krb_rd_req(&auth, KRB_SERVICE_NAME, instance, addr.sin_addr.s_addr, &adat, ""); if (r) { if (auth_debug_mode) printf("Kerberos failed him as %s\r\n", name); Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1); auth_finished(ap, AUTH_REJECT); return; } /* save the session key */ memmove(session_key, adat.session, sizeof(adat.session)); krb_kntoln(&adat, name); if (UserNameRequested && !kuserok(&adat, UserNameRequested)){ char ts[MAXPATHLEN]; struct passwd *pw = getpwnam(UserNameRequested); if(pw){ snprintf(ts, sizeof(ts), "%s%u", TKT_ROOT, (unsigned)pw->pw_uid); setenv("KRBTKFILE", ts, 1); } Data(ap, KRB_ACCEPT, NULL, 0); } else { char *msg; asprintf (&msg, "user `%s' is not authorized to " "login as `%s'", krb_unparse_name_long(adat.pname, adat.pinst, adat.prealm), UserNameRequested ? UserNameRequested : "<nobody>"); if (msg == NULL) Data(ap, KRB_REJECT, NULL, 0); else { Data(ap, KRB_REJECT, (void *)msg, -1); free(msg); } } auth_finished(ap, AUTH_USER); break; case KRB_CHALLENGE: #ifndef ENCRYPTION Data(ap, KRB_RESPONSE, NULL, 0); #else if(!VALIDKEY(session_key)){ Data(ap, KRB_RESPONSE, NULL, 0); break; } des_key_sched(&session_key, sched); { des_cblock d_block; int i; Session_Key skey; memmove(d_block, data, sizeof(d_block)); /* make a session key for encryption */ des_ecb_encrypt(&d_block, &session_key, sched, 1); skey.type=SK_DES; skey.length=8; skey.data=session_key; encrypt_session_key(&skey, 1); /* decrypt challenge, add one and encrypt it */ des_ecb_encrypt(&d_block, &challenge, sched, 0); for (i = 7; i >= 0; i--) if(++challenge[i] != 0) break; des_ecb_encrypt(&challenge, &challenge, sched, 1); Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge)); } #endif break; case KRB_FORWARD: { des_key_schedule ks; unsigned char netcred[sizeof(CREDENTIALS)]; CREDENTIALS cred; int ret; if(cnt > sizeof(cred)) abort(); des_set_key(&session_key, ks); des_pcbc_encrypt((void*)data, (void*)netcred, cnt, ks, &session_key, DES_DECRYPT); unpack_cred(netcred, cnt, &cred); { if(strcmp(cred.service, KRB_TICKET_GRANTING_TICKET) || strncmp(cred.instance, cred.realm, sizeof(cred.instance)) || cred.lifetime < 0 || cred.lifetime > 255 || cred.kvno < 0 || cred.kvno > 255 || cred.issue_date < 0 || cred.issue_date > time(0) + CLOCK_SKEW || strncmp(cred.pname, adat.pname, sizeof(cred.pname)) || strncmp(cred.pinst, adat.pinst, sizeof(cred.pname))){ Data(ap, KRB_FORWARD_REJECT, "Bad credentials", -1); }else{ if((ret = tf_setup(&cred, cred.pname, cred.pinst)) == KSUCCESS){ struct passwd *pw = getpwnam(UserNameRequested); if (pw) chown(tkt_string(), pw->pw_uid, pw->pw_gid); Data(ap, KRB_FORWARD_ACCEPT, 0, 0); } else{ Data(ap, KRB_FORWARD_REJECT, krb_get_err_text(ret), -1); } } } memset(data, 0, cnt); memset(ks, 0, sizeof(ks)); memset(&cred, 0, sizeof(cred)); } break; default: if (auth_debug_mode) printf("Unknown Kerberos option %d\r\n", data[-1]); Data(ap, KRB_REJECT, 0, 0); break; } }
/* * convert an arbitrary length string to a DES key */ void des_string_to_key(char *str, register des_cblock * key) { register char *in_str; register unsigned temp, i, j; register afs_int32 length; unsigned char *k_p; int forward; register char *p_char; char k_char[64]; des_key_schedule key_sked; in_str = str; forward = 1; p_char = k_char; length = strlen(str); /* init key array for bits */ memset(k_char, 0, sizeof(k_char)); #ifdef DEBUG if (des_debug) fprintf(stdout, "\n\ninput str length = %d string = %s\nstring = 0x ", length, str); #endif /* get next 8 bytes, strip parity, xor */ for (i = 1; i <= length; i++) { /* get next input key byte */ temp = (unsigned int)*str++; #ifdef DEBUG if (des_debug) fprintf(stdout, "%02x ", temp & 0xff); #endif /* loop through bits within byte, ignore parity */ for (j = 0; j <= 6; j++) { if (forward) *p_char++ ^= (int)temp & 01; else *--p_char ^= (int)temp & 01; temp = temp >> 1; } while (--j > 0); /* check and flip direction */ if ((i % 8) == 0) forward = !forward; } /* now stuff into the key des_cblock, and force odd parity */ p_char = k_char; k_p = (unsigned char *)key; for (i = 0; i <= 7; i++) { temp = 0; for (j = 0; j <= 6; j++) temp |= *p_char++ << (1 + j); *k_p++ = (unsigned char)temp; } /* fix key parity */ des_fixup_key_parity(key); /* Now one-way encrypt it with the folded key */ (void)des_key_sched(key, key_sked); (void)des_cbc_cksum((des_cblock *) in_str, key, length, key_sked, key); /* erase key_sked */ memset((char *)key_sked, 0, sizeof(key_sked)); /* now fix up key parity again */ des_fixup_key_parity(key); if (des_debug) fprintf(stdout, "\nResulting string_to_key = 0x%lx 0x%lx\n", *((afs_uint32 *) key), *((afs_uint32 *) key + 1)); }
int mr_send_auth(int conn, char *host_name) { #ifdef HAVE_KRB4 KTEXT_ST ticket_st; int code, auth_version = 2; long response; code = get_mr_update_ticket(host_name, &ticket_st); if (code) return code; code = send_string(conn, "AUTH_002", 9); if (code) return code; code = recv_int(conn, &response); if (code) return code; if (response) { code = send_string(conn, "AUTH_001", 9); if (code) return code; code = recv_int(conn, &response); if (code) return code; if (response) return response; auth_version = 1; } code = send_string(conn, (char *)ticket_st.dat, ticket_st.length); if (code) return code; code = recv_int(conn, &response); if (code) return code; if (response) return response; if (auth_version == 2) { des_key_schedule sched; C_Block enonce; char *data; size_t size; code = recv_string(conn, &data, &size); if (code) return code; des_key_sched(session, sched); des_ecb_encrypt((des_cblock *)data, &enonce, sched, 1); free(data); code = send_string(conn, (char *)enonce, sizeof(enonce)); if (code) return code; code = recv_int(conn, &response); if (code) return code; if (response) return response; } return MR_SUCCESS; #else return MR_NO_KRB4; #endif }