0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #include <ndrx_config.h>
0042 #include <string.h>
0043 #include <stdio.h>
0044 #include <stdlib.h>
0045 #include <memory.h>
0046 #include <time.h>
0047 #include <sys/time.h>
0048 #include <unistd.h>
0049 #include <stdarg.h>
0050 #include <arpa/inet.h>
0051 #include <errno.h>
0052
0053 #include <ndrstandard.h>
0054 #include <ndebug.h>
0055 #include <nstdutil.h>
0056 #include <sys_unix.h>
0057 #include <exsha1.h>
0058 #include <excrypto.h>
0059 #include <userlog.h>
0060 #include <expluginbase.h>
0061 #include <exaes.h>
0062 #include <exbase64.h>
0063
0064 #include "atmi_int.h"
0065
0066
0067
0068 #define IV_INIT { 0xab, 0xcc, 0x1b, 0xc2, \
0069 0x3d, 0xe4, 0x44, 0x11, \
0070 0x30, 0x54, 0x34, 0x09, \
0071 0xef, 0xaf, 0xfc, 0xf5 \
0072 }
0073
0074
0075
0076
0077
0078 #define CRYPTO_LEN_PFX_BYTES 4
0079
0080 #define API_ENTRY {_Nunset_error();}
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 expublic int ndrx_crypto_getkey_std(char *key_out, int key_out_bufsz)
0097 {
0098 int ret = EXSUCCEED;
0099 long len;
0100 API_ENTRY;
0101
0102
0103
0104 if (EXSUCCEED!=ndrx_sys_get_hostname(key_out, key_out_bufsz))
0105 {
0106 _Nset_error_fmt(NEUNIX, "Failed to get hostname!");
0107 EXFAIL_OUT(ret);
0108 }
0109
0110 len = strlen(key_out);
0111
0112
0113 if (len+1 < key_out_bufsz)
0114 {
0115 snprintf(key_out+len, key_out_bufsz - len, "%s",
0116 ndrx_sys_get_cur_username());
0117 }
0118
0119 #ifdef CRYPTODEBUG
0120 NDRX_LOG_EARLY(log_debug, "Password built: [%s]", key_out);
0121 #endif
0122
0123 out:
0124 return ret;
0125 }
0126
0127
0128
0129
0130
0131
0132 exprivate int ndrx_get_final_key(char *sha1key)
0133 {
0134 int ret = EXSUCCEED;
0135 char password[PATH_MAX+1];
0136
0137
0138
0139 if (ndrx_G_plugins.p_ndrx_crypto_getkey(password, sizeof(password)))
0140 {
0141 userlog("Failed to get encryption key by plugin "
0142 "function, provider: [%s]",
0143 ndrx_G_plugins.ndrx_crypto_getkey_provider);
0144
0145 _Nset_error_fmt(NEPLUGIN, "Failed to get encryption key by plugin "
0146 "function, provider: [%s]",
0147 ndrx_G_plugins.ndrx_crypto_getkey_provider);
0148
0149 EXFAIL_OUT(ret);
0150 }
0151
0152 #ifdef CRYPTODEBUG
0153 NDRX_LOG_EARLY(log_debug, "Clear password: [%s]", password);
0154 #endif
0155
0156
0157 EXSHA1( sha1key, password, strlen(password) );
0158
0159 #ifdef CRYPTODEBUG_DUMP
0160 NDRX_DUMP(log_debug, "SHA1 key", sha1key, NDRX_ENCKEY_BUFSZ);
0161 #endif
0162
0163 out:
0164 return ret;
0165 }
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 exprivate int ndrx_crypto_enc_int(char *input, long ilen, char *output, long *olen)
0176 {
0177 int ret = EXSUCCEED;
0178 char sha1key[NDRX_ENCKEY_BUFSZ];
0179 long size_estim;
0180 uint32_t *len_ind = (uint32_t *)output;
0181 uint8_t iv[] = IV_INIT;
0182
0183
0184
0185 if (EXSUCCEED!=ndrx_get_final_key(sha1key))
0186 {
0187 EXFAIL_OUT(ret);
0188 }
0189
0190
0191 size_estim =
0192 ((ilen + NDRX_ENC_BLOCK_SIZE - 1) / NDRX_ENC_BLOCK_SIZE)
0193 * NDRX_ENC_BLOCK_SIZE
0194 + CRYPTO_LEN_PFX_BYTES;
0195
0196 #ifdef CRYPTODEBUG
0197 NDRX_LOG_EARLY(log_debug, "%s: Data size: %ld, estimated: %ld, output buffer: %ld",
0198 __func__, ilen, size_estim, *olen);
0199 #endif
0200 #ifdef CRYPTODEBUG_DUMP
0201 NDRX_DUMP(log_debug, "About to encrypt: ", input, ilen);
0202 #endif
0203
0204 if (size_estim > *olen)
0205 {
0206 userlog("Encryption output buffer too short, estimated: %ld, but on input: %ld",
0207 size_estim, *olen);
0208
0209 _Nset_error_fmt(NENOSPACE, "Encryption output buffer too short, "
0210 "estimated: %ld, but on input: %ld",
0211 size_estim, *olen);
0212
0213 *olen = size_estim;
0214 EXFAIL_OUT(ret);
0215 }
0216 *olen = size_estim;
0217
0218
0219 *len_ind = htonl((uint32_t)ilen);
0220
0221 EXAES_CBC_encrypt_buffer((uint8_t*)(output+CRYPTO_LEN_PFX_BYTES),
0222 (uint8_t*)input, ilen, (const uint8_t*)sha1key, (const uint8_t*) iv);
0223
0224 #ifdef CRYPTODEBUG_DUMP
0225
0226
0227 NDRX_DUMP(log_debug, "Encrypted data block", output, *olen);
0228
0229 #endif
0230
0231 out:
0232 return ret;
0233 }
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 expublic int ndrx_crypto_enc(char *input, long ilen, char *output, long *olen)
0244 {
0245 API_ENTRY;
0246 return ndrx_crypto_enc_int(input, ilen, output, olen);
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 expublic int ndrx_crypto_dec_int(char *input, long ilen, char *output, long *olen)
0258 {
0259 int ret = EXSUCCEED;
0260 char sha1key[NDRX_ENCKEY_BUFSZ];
0261 uint32_t *len_ind = (uint32_t *)input;
0262 uint8_t iv[] = IV_INIT;
0263 long data_size = ntohl(*len_ind);
0264
0265
0266
0267 if (EXSUCCEED!=ndrx_get_final_key(sha1key))
0268 {
0269 EXFAIL_OUT(ret);
0270 }
0271
0272 #ifdef CRYPTODEBUG_DUMP
0273 NDRX_DUMP(log_debug, "About to decrypt (incl 4 byte len): ", input, ilen);
0274 #endif
0275
0276 #ifdef CRYPTODEBUG
0277 NDRX_LOG_EARLY(log_debug, "Data size: %ld, output buffer: %ld",
0278 data_size, *olen);
0279 #endif
0280
0281 if (data_size > *olen)
0282 {
0283 userlog("Decryption output buffer too short, data: %ld, output buffer: %ld",
0284 data_size, *olen);
0285
0286 _Nset_error_fmt(NENOSPACE, "Decryption output buffer too short, "
0287 "data: %ld, output buffer: %ld",
0288 data_size, *olen);
0289
0290 *olen = data_size;
0291 EXFAIL_OUT(ret);
0292 }
0293 *olen = data_size;
0294
0295 EXAES_CBC_decrypt_buffer((uint8_t*)(output),
0296 (uint8_t*)(input+CRYPTO_LEN_PFX_BYTES), ilen-CRYPTO_LEN_PFX_BYTES,
0297 (const uint8_t*)sha1key, (const uint8_t*) iv);
0298
0299
0300
0301 #ifdef CRYPTODEBUG_DUMP
0302 NDRX_DUMP(log_debug, "Decrypted data block", output, *olen);
0303 #endif
0304
0305 out:
0306 return ret;
0307 }
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 expublic int ndrx_crypto_dec(char *input, long ilen, char *output, long *olen)
0318 {
0319 API_ENTRY;
0320 return ndrx_crypto_dec_int(input, ilen, output, olen);
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330 expublic int ndrx_crypto_enc_string(char *input, char *output, long *olen)
0331 {
0332 int ret = EXSUCCEED;
0333 char *buf = NULL;
0334 long bufsz;
0335 long estim_size;
0336 long inlen = strlen(input);
0337 size_t b64len;
0338 API_ENTRY;
0339
0340 NDRX_SYSBUF_MALLOC_OUT(buf, bufsz, ret);
0341
0342
0343 if (EXSUCCEED!=ndrx_crypto_enc_int(input, inlen, buf, &bufsz))
0344 {
0345 EXFAIL_OUT(ret);
0346 }
0347
0348
0349 estim_size = NDRX_BASE64_SIZE(bufsz) + 1;
0350
0351 if (NDRX_BASE64_SIZE(bufsz) +1 > *olen)
0352 {
0353 userlog("Output buffer too short. Required for "
0354 "base64 %ld bytes, but got %ld", estim_size, *olen);
0355 #ifdef CRYPTODEBUG
0356 NDRX_LOG_EARLY(log_error, "Output buffer too short. Required for "
0357 "base64 %ld bytes, but got %ld", estim_size, *olen);
0358 #endif
0359
0360 _Nset_error_fmt(NENOSPACE, "Output buffer too short. Required for "
0361 "base64 %ld bytes, but got %ld",
0362 estim_size, *olen);
0363
0364 *olen = NDRX_BASE64_SIZE(bufsz) +1;
0365 EXFAIL_OUT(ret);
0366 }
0367
0368
0369 b64len = (size_t)*olen;
0370 ndrx_base64_encode((unsigned char *)buf, bufsz, &b64len, output);
0371
0372
0373 *olen=b64len;
0374
0375
0376 #ifdef CRYPTODEBUG
0377
0378 NDRX_LOG_EARLY(log_debug, "%s: input: [%s]", __func__, input);
0379 NDRX_LOG_EARLY(log_debug, "%s: output: [%s]", __func__, output);
0380
0381 #endif
0382
0383 out:
0384 if (NULL!=buf)
0385 {
0386 NDRX_SYSBUF_FREE(buf);
0387 }
0388 return ret;
0389 }
0390
0391
0392
0393
0394
0395
0396
0397 expublic int ndrx_crypto_dec_string(char *input, char *output, long *olen)
0398 {
0399 int ret = EXSUCCEED;
0400 long len = strlen(input);
0401 char *buf = NULL;
0402 size_t bufsz = len;
0403 uint32_t *len_ind;
0404 long data_size;
0405
0406 API_ENTRY;
0407
0408 if (NULL==(buf = NDRX_MALLOC(bufsz)))
0409 {
0410 int err = errno;
0411
0412 NDRX_LOG_EARLY(log_error, "%s: Failed to allocate %ld bytes: %s",
0413 __func__, len, strerror(err));
0414 userlog("%s: Failed to allocate %ld bytes: %s",
0415 __func__, len, strerror(err));
0416
0417 _Nset_error_fmt(NEUNIX, "%s: Failed to allocate %ld bytes: %s",
0418 __func__, len, strerror(err));
0419 EXFAIL_OUT(ret);
0420 }
0421
0422 len_ind = (uint32_t *)buf;
0423
0424 #ifdef CRYPTODEBUG
0425 NDRX_LOG_EARLY(log_debug, "%s, output buf %p, olen=%ld input len: %ld",
0426 __func__, output, *olen, len);
0427 NDRX_LOG_EARLY(log_debug, "%s: About to decrypt (b64): [%s]", __func__, input);
0428 #endif
0429
0430
0431 if (NULL==ndrx_base64_decode(input, len, &bufsz, buf))
0432 {
0433 _Nset_error_fmt(NEFORMAT, "%s, ndrx_base64_decode failed (input len: %ld) input: [%s]",
0434 __func__, len, input);
0435 NDRX_LOG_EARLY(log_error, "%s, ndrx_base64_decode failed (input len: %ld) input: [%s]",
0436 __func__, len, input);
0437 userlog("%s, ndrx_base64_decode failed (input len: %ld)",
0438 __func__, len);
0439 EXFAIL_OUT(ret);
0440 }
0441
0442 #ifdef CRYPTODEBUG_DUMP
0443 NDRX_DUMP(log_debug, "Binary data to decrypt: ", buf, bufsz);
0444 #endif
0445
0446
0447 data_size = ntohl(*len_ind);
0448
0449 if (data_size +1 > *olen)
0450 {
0451 userlog("String decryption output buffer too short, data (incl. EOS): %ld, "
0452 "output buffer: %ld", data_size+1, *olen);
0453
0454 _Nset_error_fmt(NENOSPACE, "String decryption output buffer too short, "
0455 "data (incl. EOS): %ld, output buffer: %ld",
0456 data_size+1, *olen);
0457
0458 *olen=data_size+1;
0459 EXFAIL_OUT(ret);
0460 }
0461
0462
0463
0464 if (EXSUCCEED!=ndrx_crypto_dec_int(buf, bufsz, output, olen))
0465 {
0466 #ifdef CRYPTODEBUG
0467 NDRX_LOG_EARLY(log_error, "%s: Failed to decrypt [%s]!", __func__, input);
0468 #endif
0469 userlog("%s: Failed to decrypt [%s]!", __func__, input);
0470 }
0471
0472 output[*olen] = EXEOS;
0473
0474
0475
0476
0477
0478 if ((len=strlen(output)) != *olen)
0479 {
0480 userlog("Found EOS at %ld. Output data len %ld", len, *olen);
0481
0482 _Nset_error_fmt(NEINVALKEY, "Found EOS at %ld. Output data len %ld",
0483 len, *olen);
0484
0485 EXFAIL_OUT(ret);
0486 }
0487
0488
0489 (*olen)++;
0490
0491 out:
0492
0493 if (NULL!=buf)
0494 {
0495 NDRX_FREE(buf);
0496 }
0497
0498 return ret;
0499 }
0500