1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * Copyright (c) 1990 Dennis Ferguson. All rights reserved. 9 * 10 * Commercial use is permitted only if products which are derived from 11 * or include this software are made available for purchase and/or use 12 * in Canada. Otherwise, redistribution and use in source and binary 13 * forms are permitted. 14 */ 15 16 /* 17 * des_cbc_encrypt.c - an implementation of the DES cipher function in cbc mode 18 */ 19 #include "des_int.h" 20 21 /* 22 * des_cbc_encrypt - {en,de}crypt a stream in CBC mode 23 */ 24 25 /* SUNW14resync - sparcv9 cc complained about lack of object init */ 26 /* = all zero */ 27 const mit_des_cblock mit_des_zeroblock = {0, 0, 0, 0, 0, 0, 0, 0}; 28 29 #undef mit_des_cbc_encrypt 30 31 #ifndef _KERNEL 32 int 33 mit_des_cbc_encrypt(context, in, out, length, key, ivec, encrypt) 34 krb5_context context; 35 const mit_des_cblock *in; 36 mit_des_cblock *out; 37 long length; 38 krb5_keyblock *key; 39 mit_des_cblock ivec; 40 int encrypt; 41 { 42 krb5_error_code ret = KRB5_PROG_ETYPE_NOSUPP; 43 /* EXPORT DELETE START */ 44 KRB5_MECH_TO_PKCS algos; 45 CK_MECHANISM mechanism; 46 CK_RV rv; 47 /* For the Key Object */ 48 49 ret = 0; 50 if ((rv = get_algo(key->enctype, &algos)) != CKR_OK) { 51 KRB5_LOG0(KRB5_ERR, "failure to get algo id in function " 52 "mit_des_cbc_encrypt."); 53 ret = PKCS_ERR; 54 goto cleanup; 55 } 56 57 rv = init_key_uef(krb_ctx_hSession(context), key); 58 if (rv != CKR_OK) { 59 KRB5_LOG(KRB5_ERR, "init_key_uef failed in " 60 "mit_des_cbc_encrypt: rv = 0x%x", rv); 61 ret = PKCS_ERR; 62 goto cleanup; 63 } 64 65 mechanism.mechanism = algos.enc_algo; 66 mechanism.pParameter = ivec; 67 if (ivec != NULL) 68 mechanism.ulParameterLen = MIT_DES_BLOCK_LENGTH; 69 else 70 mechanism.ulParameterLen = 0; 71 72 if (encrypt) 73 rv = C_EncryptInit(krb_ctx_hSession(context), &mechanism, key->hKey); 74 else 75 rv = C_DecryptInit(krb_ctx_hSession(context), &mechanism, key->hKey); 76 77 if (rv != CKR_OK) { 78 KRB5_LOG(KRB5_ERR, "C_EncryptInit/C_DecryptInit failed in " 79 "mit_des_cbc_encrypt: rv = 0x%x", rv); 80 ret = PKCS_ERR; 81 goto cleanup; 82 } 83 84 if (encrypt) 85 rv = C_Encrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in, 86 (CK_ULONG)length, (CK_BYTE_PTR)out, 87 (CK_ULONG_PTR)&length); 88 else 89 rv = C_Decrypt(krb_ctx_hSession(context), (CK_BYTE_PTR)in, 90 (CK_ULONG)length, (CK_BYTE_PTR)out, 91 (CK_ULONG_PTR)&length); 92 93 if (rv != CKR_OK) { 94 KRB5_LOG(KRB5_ERR, 95 "C_Encrypt/C_Decrypt failed in mit_des_cbc_encrypt: " 96 "rv = 0x%x", rv); 97 ret = PKCS_ERR; 98 } 99 cleanup: 100 101 final_cleanup: 102 if (ret) 103 (void) memset(out, 0, length); 104 105 /* EXPORT DELETE END */ 106 KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() end retval=%d", ret); 107 108 return(ret); 109 } 110 #else 111 112 /* 113 * This routine performs DES cipher-block-chaining operation, either 114 * encrypting from cleartext to ciphertext, if encrypt != 0 or 115 * decrypting from ciphertext to cleartext, if encrypt == 0. 116 * 117 * The key schedule is passed as an arg, as well as the cleartext or 118 * ciphertext. The cleartext and ciphertext should be in host order. 119 * 120 * NOTE-- the output is ALWAYS an multiple of 8 bytes long. If not 121 * enough space was provided, your program will get trashed. 122 * 123 * For encryption, the cleartext string is null padded, at the end, to 124 * an integral multiple of eight bytes. 125 * 126 * For decryption, the ciphertext will be used in integral multiples 127 * of 8 bytes, but only the first "length" bytes returned into the 128 * cleartext. 129 */ 130 131 /* ARGSUSED */ 132 int 133 mit_des_cbc_encrypt(krb5_context context, 134 const mit_des_cblock *in, 135 mit_des_cblock *out, 136 long length, krb5_keyblock *key, 137 mit_des_cblock ivec, int encrypt) 138 { 139 int ret = KRB5_PROG_ETYPE_NOSUPP; 140 /* EXPORT DELETE START */ 141 krb5_data ivdata; 142 ret = 0; 143 144 KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() start encrypt=%d", encrypt); 145 146 ivdata.data = (char *)ivec; 147 ivdata.length = sizeof(mit_des_cblock); 148 149 ret = k5_ef_crypto((const char *)in, 150 (char *)out, length, key, &ivdata, encrypt); 151 152 /* EXPORT DELETE END */ 153 KRB5_LOG(KRB5_INFO, "mit_des_cbc_encrypt() end retval=%d", ret); 154 return(ret); 155 } 156 #endif /* !_KERNEL */ 157