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; }
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; } }
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((uint8_t *)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((const unsigned char*) clear_ticket, (unsigned char*) clear_ticket, len, key_schedule, (C_Block *)key.key, 1); ZERO_STRUCT(key); *ticket = data_blob(clear_ticket, len); return true; }
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, False); /* Our client code needs the the key in the clear, it does not know the server-key ... */ memcpy(ct->HandShakeKey, p, 8); p += 8; /* Ticket lifetime. We fake everything here, so go as long as possible. This is in 5-minute intervals, so 255 is 21 hours and 15 minutes.*/ *p = 255; p += 1; /* Ticket creation time */ now = time(NULL); SIVAL(p, 0, now); ct->BeginTimestamp = now; ct->EndTimestamp = now + (255*60*5); 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; }
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; }
int des_enc_read(int fd, void *buf, int len, des_key_schedule sched, des_cblock *iv) { /* data to be unencrypted */ int net_num=0; static unsigned char *net=NULL; /* extra unencrypted data * for when a block of 100 comes in but is des_read one byte at * a time. */ static unsigned char *unnet=NULL; static int unnet_start=0; static int unnet_left=0; static unsigned char *tmpbuf=NULL; int i; long num=0,rnum; unsigned char *p; if (tmpbuf == NULL) { tmpbuf=OPENSSL_malloc(BSIZE); if (tmpbuf == NULL) return(-1); } if (net == NULL) { net=OPENSSL_malloc(BSIZE); if (net == NULL) return(-1); } if (unnet == NULL) { unnet=OPENSSL_malloc(BSIZE); if (unnet == NULL) return(-1); } /* left over data from last decrypt */ if (unnet_left != 0) { if (unnet_left < len) { /* we still still need more data but will return * with the number of bytes we have - should always * check the return value */ memcpy(buf,&(unnet[unnet_start]), unnet_left); /* eay 26/08/92 I had the next 2 lines * reversed :-( */ i=unnet_left; unnet_start=unnet_left=0; } else { memcpy(buf,&(unnet[unnet_start]),len); unnet_start+=len; unnet_left-=len; i=len; } return(i); } /* We need to get more data. */ if (len > MAXWRITE) len=MAXWRITE; /* first - get the length */ while (net_num < HDRSIZE) { i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); #ifdef EINTR if ((i == -1) && (errno == EINTR)) continue; #endif if (i <= 0) return(0); net_num+=i; } /* we now have at net_num bytes in net */ p=net; /* num=0; */ n2l(p,num); /* num should be rounded up to the next group of eight * we make sure that we have read a multiple of 8 bytes from the net. */ if ((num > MAXWRITE) || (num < 0)) /* error */ return(-1); rnum=(num < 8)?8:((num+7)/8*8); net_num=0; while (net_num < rnum) { i=read(fd,(void *)&(net[net_num]),rnum-net_num); #ifdef EINTR if ((i == -1) && (errno == EINTR)) continue; #endif if (i <= 0) return(0); net_num+=i; } /* Check if there will be data left over. */ if (len < num) { if (des_rw_mode & DES_PCBC_MODE) des_pcbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT); else des_cbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT); memcpy(buf,unnet,len); unnet_start=len; unnet_left=num-len; /* The following line is done because we return num * as the number of bytes read. */ num=len; } else { /* >output is a multiple of 8 byes, if len < rnum * >we must be careful. The user must be aware that this * >routine will write more bytes than he asked for. * >The length of the buffer must be correct. * FIXED - Should be ok now 18-9-90 - eay */ if (len < rnum) { if (des_rw_mode & DES_PCBC_MODE) des_pcbc_encrypt(net,tmpbuf,num,sched,iv, DES_DECRYPT); else des_cbc_encrypt(net,tmpbuf,num,sched,iv, DES_DECRYPT); /* eay 26/08/92 fix a bug that returned more * bytes than you asked for (returned len bytes :-( */ memcpy(buf,tmpbuf,num); } else { if (des_rw_mode & DES_PCBC_MODE) des_pcbc_encrypt(net,buf,num,sched,iv, DES_DECRYPT); else des_cbc_encrypt(net,buf,num,sched,iv, DES_DECRYPT); } } return num; }
int main(int argc, char *argv[]) { int j,err=0; unsigned int i; des_cblock in,out,outin,iv3,iv2; des_key_schedule ks,ks2,ks3; unsigned char cbc_in[40]; unsigned char cbc_out[40]; DES_LONG cs; unsigned char cret[8]; #ifdef _CRAY struct { int a:32; int b:32; } lqret[2]; #else DES_LONG lqret[4]; #endif int num; char *str; #ifndef OPENSSL_NO_DESCBCM TINYCLR_SSL_PRINTF("Doing cbcm\n"); if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } TINYCLR_SSL_MEMSET(cbc_out,0,40); TINYCLR_SSL_MEMSET(cbc_in,0,40); i=TINYCLR_SSL_STRLEN((char *)cbc_data)+1; /* i=((i+7)/8)*8; */ TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); TINYCLR_SSL_MEMSET(iv2,'\0',sizeof iv2); DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2, DES_ENCRYPT); DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3, &iv3,&iv2,DES_ENCRYPT); /* if (memcmp(cbc_out,cbc3_ok, (unsigned int)(TINYCLR_SSL_STRLEN((char *)cbc_data)+1+7)/8*8) != 0) { TINYCLR_SSL_PRINTF("des_ede3_cbc_encrypt encrypt error\n"); err=1; } */ TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); TINYCLR_SSL_MEMSET(iv2,'\0',sizeof iv2); DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0) { unsigned int n; TINYCLR_SSL_PRINTF("des_ede3_cbcm_encrypt decrypt error\n"); for(n=0 ; n < i ; ++n) TINYCLR_SSL_PRINTF(" %02x",cbc_data[n]); TINYCLR_SSL_PRINTF("\n"); for(n=0 ; n < i ; ++n) TINYCLR_SSL_PRINTF(" %02x",cbc_in[n]); TINYCLR_SSL_PRINTF("\n"); err=1; } #endif TINYCLR_SSL_PRINTF("Doing ecb\n"); for (i=0; i<NUM_TESTS; i++) { DES_set_key_unchecked(&key_data[i],&ks); TINYCLR_SSL_MEMCPY(in,plain_data[i],8); TINYCLR_SSL_MEMSET(out,0,8); TINYCLR_SSL_MEMSET(outin,0,8); des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT); des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(out,cipher_data[i],8) != 0) { TINYCLR_SSL_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 (TINYCLR_SSL_MEMCMP(in,outin,8) != 0) { TINYCLR_SSL_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 TINYCLR_SSL_PRINTF("Doing ede ecb\n"); for (i=0; i<(NUM_TESTS-2); i++) { DES_set_key_unchecked(&key_data[i],&ks); DES_set_key_unchecked(&key_data[i+1],&ks2); DES_set_key_unchecked(&key_data[i+2],&ks3); TINYCLR_SSL_MEMCPY(in,plain_data[i],8); TINYCLR_SSL_MEMSET(out,0,8); TINYCLR_SSL_MEMSET(outin,0,8); des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT); des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(out,cipher_ecb2[i],8) != 0) { TINYCLR_SSL_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 (TINYCLR_SSL_MEMCMP(in,outin,8) != 0) { TINYCLR_SSL_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 TINYCLR_SSL_PRINTF("Doing cbc\n"); if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } TINYCLR_SSL_MEMSET(cbc_out,0,40); TINYCLR_SSL_MEMSET(cbc_in,0,40); TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); des_ncbc_encrypt(cbc_data,cbc_out,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &iv3,DES_ENCRYPT); if (TINYCLR_SSL_MEMCMP(cbc_out,cbc_ok,32) != 0) { TINYCLR_SSL_PRINTF("cbc_encrypt encrypt error\n"); err=1; } TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); des_ncbc_encrypt(cbc_out,cbc_in,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &iv3,DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)) != 0) { TINYCLR_SSL_PRINTF("cbc_encrypt decrypt error\n"); err=1; } #ifndef LIBDES_LIT TINYCLR_SSL_PRINTF("Doing desx cbc\n"); if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } TINYCLR_SSL_MEMSET(cbc_out,0,40); TINYCLR_SSL_MEMSET(cbc_in,0,40); TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); des_xcbc_encrypt(cbc_data,cbc_out,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT); if (TINYCLR_SSL_MEMCMP(cbc_out,xcbc_ok,32) != 0) { TINYCLR_SSL_PRINTF("des_xcbc_encrypt encrypt error\n"); err=1; } TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); des_xcbc_encrypt(cbc_out,cbc_in,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0) { TINYCLR_SSL_PRINTF("des_xcbc_encrypt decrypt error\n"); err=1; } #endif TINYCLR_SSL_PRINTF("Doing ede cbc\n"); if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } TINYCLR_SSL_MEMSET(cbc_out,0,40); TINYCLR_SSL_MEMSET(cbc_in,0,40); i=TINYCLR_SSL_STRLEN((char *)cbc_data)+1; /* i=((i+7)/8)*8; */ TINYCLR_SSL_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[16]),&(cbc_out[16]),i-16,ks,ks2,ks3, &iv3,DES_ENCRYPT); if (TINYCLR_SSL_MEMCMP(cbc_out,cbc3_ok, (unsigned int)(TINYCLR_SSL_STRLEN((char *)cbc_data)+1+7)/8*8) != 0) { unsigned int n; TINYCLR_SSL_PRINTF("des_ede3_cbc_encrypt encrypt error\n"); for(n=0 ; n < i ; ++n) TINYCLR_SSL_PRINTF(" %02x",cbc_out[n]); TINYCLR_SSL_PRINTF("\n"); for(n=0 ; n < i ; ++n) TINYCLR_SSL_PRINTF(" %02x",cbc3_ok[n]); TINYCLR_SSL_PRINTF("\n"); err=1; } TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv)); des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0) { unsigned int n; TINYCLR_SSL_PRINTF("des_ede3_cbc_encrypt decrypt error\n"); for(n=0 ; n < i ; ++n) TINYCLR_SSL_PRINTF(" %02x",cbc_data[n]); TINYCLR_SSL_PRINTF("\n"); for(n=0 ; n < i ; ++n) TINYCLR_SSL_PRINTF(" %02x",cbc_in[n]); TINYCLR_SSL_PRINTF("\n"); err=1; } #ifndef LIBDES_LIT TINYCLR_SSL_PRINTF("Doing pcbc\n"); if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0) { TINYCLR_SSL_PRINTF("Key error %d\n",j); err=1; } TINYCLR_SSL_MEMSET(cbc_out,0,40); TINYCLR_SSL_MEMSET(cbc_in,0,40); des_pcbc_encrypt(cbc_data,cbc_out,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &cbc_iv,DES_ENCRYPT); if (TINYCLR_SSL_MEMCMP(cbc_out,pcbc_ok,32) != 0) { TINYCLR_SSL_PRINTF("pcbc_encrypt encrypt error\n"); err=1; } des_pcbc_encrypt(cbc_out,cbc_in,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,&cbc_iv, DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0) { TINYCLR_SSL_PRINTF("pcbc_encrypt decrypt error\n"); err=1; } TINYCLR_SSL_PRINTF("Doing "); TINYCLR_SSL_PRINTF("cfb8 "); err+=cfb_test(8,cfb_cipher8); TINYCLR_SSL_PRINTF("cfb16 "); err+=cfb_test(16,cfb_cipher16); TINYCLR_SSL_PRINTF("cfb32 "); err+=cfb_test(32,cfb_cipher32); TINYCLR_SSL_PRINTF("cfb48 "); err+=cfb_test(48,cfb_cipher48); TINYCLR_SSL_PRINTF("cfb64 "); err+=cfb_test(64,cfb_cipher64); TINYCLR_SSL_PRINTF("cfb64() "); err+=cfb64_test(cfb_cipher64); TINYCLR_SSL_MEMCPY(cfb_tmp,cfb_iv,sizeof(cfb_iv)); for (i=0; i<sizeof(plain); i++) des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]), 8,1,ks,&cfb_tmp,DES_ENCRYPT); if (TINYCLR_SSL_MEMCMP(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0) { TINYCLR_SSL_PRINTF("cfb_encrypt small encrypt error\n"); err=1; } TINYCLR_SSL_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,1,ks,&cfb_tmp,DES_DECRYPT); if (TINYCLR_SSL_MEMCMP(plain,cfb_buf2,sizeof(plain)) != 0) { TINYCLR_SSL_PRINTF("cfb_encrypt small decrypt error\n"); err=1; } TINYCLR_SSL_PRINTF("ede_cfb64() "); err+=ede_cfb64_test(cfb_cipher64); TINYCLR_SSL_PRINTF("done\n"); TINYCLR_SSL_PRINTF("Doing ofb\n"); DES_set_key_checked(&ofb_key,&ks); TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv)); des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp); if (TINYCLR_SSL_MEMCMP(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) { TINYCLR_SSL_PRINTF("ofb_encrypt encrypt error\n"); TINYCLR_SSL_PRINTF("%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]); TINYCLR_SSL_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; } TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv)); des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp); if (TINYCLR_SSL_MEMCMP(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) { TINYCLR_SSL_PRINTF("ofb_encrypt decrypt error\n"); TINYCLR_SSL_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]); TINYCLR_SSL_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; } TINYCLR_SSL_PRINTF("Doing ofb64\n"); DES_set_key_checked(&ofb_key,&ks); TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv)); TINYCLR_SSL_MEMSET(ofb_buf1,0,sizeof(ofb_buf1)); TINYCLR_SSL_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,&ofb_tmp, &num); } if (TINYCLR_SSL_MEMCMP(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) { TINYCLR_SSL_PRINTF("ofb64_encrypt encrypt error\n"); err=1; } TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv)); num=0; des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp, &num); if (TINYCLR_SSL_MEMCMP(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) { TINYCLR_SSL_PRINTF("ofb64_encrypt decrypt error\n"); err=1; } TINYCLR_SSL_PRINTF("Doing ede_ofb64\n"); DES_set_key_checked(&ofb_key,&ks); TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv)); TINYCLR_SSL_MEMSET(ofb_buf1,0,sizeof(ofb_buf1)); TINYCLR_SSL_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,&ofb_tmp,&num); } if (TINYCLR_SSL_MEMCMP(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) { TINYCLR_SSL_PRINTF("ede_ofb64_encrypt encrypt error\n"); err=1; } TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv)); num=0; des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,ks,ks, &ofb_tmp,&num); if (TINYCLR_SSL_MEMCMP(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) { TINYCLR_SSL_PRINTF("ede_ofb64_encrypt decrypt error\n"); err=1; } TINYCLR_SSL_PRINTF("Doing cbc_cksum\n"); DES_set_key_checked(&cbc_key,&ks); cs=des_cbc_cksum(cbc_data,&cret,TINYCLR_SSL_STRLEN((char *)cbc_data),ks,&cbc_iv); if (cs != cbc_cksum_ret) { TINYCLR_SSL_PRINTF("bad return value (%08lX), should be %08lX\n", (unsigned long)cs,(unsigned long)cbc_cksum_ret); err=1; } if (TINYCLR_SSL_MEMCMP(cret,cbc_cksum_data,8) != 0) { TINYCLR_SSL_PRINTF("bad cbc_cksum block returned\n"); err=1; } TINYCLR_SSL_PRINTF("Doing quad_cksum\n"); cs=des_quad_cksum(cbc_data,(des_cblock *)lqret, (long)TINYCLR_SSL_STRLEN((char *)cbc_data),2,(des_cblock *)cbc_iv); if (cs != 0x70d7a63aL) { TINYCLR_SSL_PRINTF("quad_cksum error, ret %08lx should be 70d7a63a\n", (unsigned long)cs); err=1; } #ifdef _CRAY if (lqret[0].a != 0x327eba8dL) { TINYCLR_SSL_PRINTF("quad_cksum error, out[0] %08lx is not %08lx\n", (unsigned long)lqret[0].a,0x327eba8dUL); err=1; } if (lqret[0].b != 0x201a49ccL) { TINYCLR_SSL_PRINTF("quad_cksum error, out[1] %08lx is not %08lx\n", (unsigned long)lqret[0].b,0x201a49ccUL); err=1; } if (lqret[1].a != 0x70d7a63aL) { TINYCLR_SSL_PRINTF("quad_cksum error, out[2] %08lx is not %08lx\n", (unsigned long)lqret[1].a,0x70d7a63aUL); err=1; } if (lqret[1].b != 0x501c2c26L) { TINYCLR_SSL_PRINTF("quad_cksum error, out[3] %08lx is not %08lx\n", (unsigned long)lqret[1].b,0x501c2c26UL); err=1; } #else if (lqret[0] != 0x327eba8dL) { TINYCLR_SSL_PRINTF("quad_cksum error, out[0] %08lx is not %08lx\n", (unsigned long)lqret[0],0x327eba8dUL); err=1; } if (lqret[1] != 0x201a49ccL) { TINYCLR_SSL_PRINTF("quad_cksum error, out[1] %08lx is not %08lx\n", (unsigned long)lqret[1],0x201a49ccUL); err=1; } if (lqret[2] != 0x70d7a63aL) { TINYCLR_SSL_PRINTF("quad_cksum error, out[2] %08lx is not %08lx\n", (unsigned long)lqret[2],0x70d7a63aUL); err=1; } if (lqret[3] != 0x501c2c26L) { TINYCLR_SSL_PRINTF("quad_cksum error, out[3] %08lx is not %08lx\n", (unsigned long)lqret[3],0x501c2c26UL); err=1; } #endif #endif TINYCLR_SSL_PRINTF("input word alignment test"); for (i=0; i<4; i++) { TINYCLR_SSL_PRINTF(" %d",i); des_ncbc_encrypt(&(cbc_out[i]),cbc_in, TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &cbc_iv,DES_ENCRYPT); } TINYCLR_SSL_PRINTF("\noutput word alignment test"); for (i=0; i<4; i++) { TINYCLR_SSL_PRINTF(" %d",i); des_ncbc_encrypt(cbc_out,&(cbc_in[i]), TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks, &cbc_iv,DES_ENCRYPT); } TINYCLR_SSL_PRINTF("\n"); TINYCLR_SSL_PRINTF("fast crypt test "); str=crypt("testing","ef"); if (TINYCLR_SSL_STRCMP("efGnQx2725bI2",str) != 0) { TINYCLR_SSL_PRINTF("fast crypt error, %s should be efGnQx2725bI2\n",str); err=1; } str=crypt("bca76;23","yA"); if (TINYCLR_SSL_STRCMP("yA1Rp/1hZXIJk",str) != 0) { TINYCLR_SSL_PRINTF("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str); err=1; } #ifdef OPENSSL_SYS_NETWARE if (err) TINYCLR_SSL_PRINTF("ERROR: %d\n", err); #endif TINYCLR_SSL_PRINTF("\n"); return(err); }
int32_t krb_rd_priv(void *in, u_int32_t in_length, struct des_ks_struct *schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver, MSG_DAT *m_data) { unsigned char *p = (unsigned char*)in; int little_endian; u_int32_t clen; struct timeval tv; u_int32_t src_addr; int delta_t; unsigned char pvno, type; pvno = *p++; if(pvno != KRB_PROT_VERSION) return RD_AP_VERSION; type = *p++; little_endian = type & 1; type &= ~1; p += krb_get_int(p, &clen, 4, little_endian); if(clen + 2 > in_length) return RD_AP_MODIFIED; des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, schedule, key, DES_DECRYPT); p += krb_get_int(p, &m_data->app_length, 4, little_endian); if(m_data->app_length + 17 > in_length) return RD_AP_MODIFIED; m_data->app_data = p; p += m_data->app_length; m_data->time_5ms = *p++; p += krb_get_address(p, &src_addr); if (!krb_equiv(src_addr, sender->sin_addr.s_addr)) return RD_AP_BADD; p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian); m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver); gettimeofday(&tv, NULL); /* check the time integrity of the msg */ delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec)); if (delta_t > CLOCK_SKEW) return RD_AP_TIME; if (krb_debug) krb_warning("delta_t = %d\n", (int) delta_t); /* * caller must check timestamps for proper order and * replays, since server might have multiple clients * each with its own timestamps and we don't assume * tightly synchronized clocks. */ return KSUCCESS; }