/* Prep and encrypt using Rijndael */ static int _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key) { char *plain; char *b64cipher; unsigned char *cipher; int cipher_len; /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 4); if(plain == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); snprintf(plain, strlen(ctx->encoded_msg) + strlen(ctx->digest) + 4, "%s:%s", ctx->encoded_msg, ctx->digest); /* Make a bucket for the encrypted version and populate it. */ cipher = malloc(strlen(plain) + 32); /* Plus padding for salt and Block */ if(cipher == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); cipher_len = rij_encrypt( (unsigned char*)plain, strlen(plain), (char*)enc_key, cipher ); /* Now make a bucket for the base64-encoded version and populate it. */ b64cipher = malloc(((cipher_len / 3) * 4) + 8); if(b64cipher == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); b64_encode(cipher, b64cipher, cipher_len); strip_b64_eq(b64cipher); ctx->encrypted_msg = strdup(b64cipher); /* Clean-up */ free(plain); free(cipher); free(b64cipher); if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); }
/* Prep and encrypt using Rijndael */ static int _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) { char *plaintext; char *b64ciphertext; unsigned char *ciphertext; int cipher_len; int pt_len; int zero_free_rv = FKO_SUCCESS; if(enc_key_len > RIJNDAEL_MAX_KEYSIZE) return(FKO_ERROR_INVALID_KEY_LEN); if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL); switch(ctx->digest_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL); } pt_len = ctx->encoded_msg_len + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2; /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plaintext = calloc(1, pt_len); if(plaintext == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); pt_len = snprintf(plaintext, pt_len, "%s:%s", ctx->encoded_msg, ctx->digest); if(! is_valid_pt_msg_len(pt_len)) { if(zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } /* Make a bucket for the encrypted version and populate it. */ ciphertext = calloc(1, pt_len + 32); /* Plus padding for salt and Block */ if(ciphertext == NULL) { if(zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } cipher_len = rij_encrypt( (unsigned char*)plaintext, pt_len, (char*)enc_key, enc_key_len, ciphertext, ctx->encryption_mode ); /* Now make a bucket for the base64-encoded version and populate it. */ b64ciphertext = malloc(((cipher_len / 3) * 4) + 8); if(b64ciphertext == NULL) { if(zero_free((char *) ciphertext, pt_len+32) == FKO_SUCCESS && zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } b64_encode(ciphertext, b64ciphertext, cipher_len); strip_b64_eq(b64ciphertext); if(ctx->encrypted_msg != NULL) zero_free_rv = zero_free(ctx->encrypted_msg, strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)); ctx->encrypted_msg = strdup(b64ciphertext); ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE); /* Clean-up */ if(zero_free(plaintext, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free((char *) ciphertext, pt_len+32) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free(b64ciphertext, strnlen(b64ciphertext, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL); return(zero_free_rv); }