X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fcrypto.c;h=07c078cdadd810be615747d6280d934db9a46cdf;hb=79cb8bb8418cca0c408db3c79d78fa23d5e18564;hp=9be58e5852d09ad2d9af7b3d491f6c0c3057f99c;hpb=63dbb99337d0423253cb1ead0dcc3da54af5d13e;p=mod_auth_gssapi.git diff --git a/src/crypto.c b/src/crypto.c index 9be58e5..07c078c 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -13,66 +13,110 @@ struct seal_key { unsigned char *hkey; }; -apr_status_t SEAL_KEY_CREATE(struct seal_key **skey) +apr_status_t SEAL_KEY_CREATE(apr_pool_t *p, struct seal_key **skey, + struct databuf *keys) { struct seal_key *n; + int keylen; int ret; - n = calloc(1, sizeof(*n)); + n = apr_pcalloc(p, sizeof(*n)); if (!n) return ENOMEM; n->cipher = EVP_aes_128_cbc(); if (!n->cipher) { - free(n); - return EFAULT; + ret = EFAULT; + goto done; } + keylen = n->cipher->key_len; + n->md = EVP_sha256(); if (!n->md) { - free(n); - return EFAULT; + ret = EFAULT; + goto done; } - n->ekey = malloc(n->cipher->key_len); + n->ekey = apr_palloc(p, keylen); if (!n->ekey) { - free(n); - return ENOMEM; + ret = ENOMEM; + goto done; } - n->hkey = malloc(n->cipher->key_len); + n->hkey = apr_palloc(p, keylen); if (!n->hkey) { - free(n); - return ENOMEM; + ret = ENOMEM; + goto done; } - ret = RAND_bytes(n->ekey, n->cipher->key_len); - if (ret == 0) { - free(n->ekey); - free(n->hkey); - free(n); - return EFAULT; + if (keys) { + if (keys->length != (keylen * 2)) { + ret = EINVAL; + goto done; + } + memcpy(n->ekey, keys->value, keylen); + memcpy(n->hkey, keys->value + keylen, keylen); + } else { + ret = apr_generate_random_bytes(n->ekey, keylen); + if (ret != 0) { + ret = EFAULT; + goto done; + } + + ret = apr_generate_random_bytes(n->hkey, keylen); + if (ret != 0) { + ret = EFAULT; + goto done; + } } - ret = RAND_bytes(n->hkey, n->cipher->key_len); - if (ret == 0) { + ret = 0; +done: + if (ret) { free(n->ekey); free(n->hkey); free(n); - return EFAULT; + } else { + *skey = n; } + return ret; +} - *skey = n; +apr_status_t HMAC_BUFFER(struct seal_key *skey, struct databuf *buffer, + struct databuf *result) +{ + HMAC_CTX hmac_ctx = { 0 }; + unsigned int len; + int ret; + + /* now MAC the buffer */ + HMAC_CTX_init(&hmac_ctx); + + ret = HMAC_Init_ex(&hmac_ctx, skey->hkey, + skey->cipher->key_len, skey->md, NULL); + if (ret == 0) goto done; + + ret = HMAC_Update(&hmac_ctx, buffer->value, buffer->length); + if (ret == 0) goto done; + + ret = HMAC_Final(&hmac_ctx, result->value, &len); + +done: + HMAC_CTX_cleanup(&hmac_ctx); + if (ret == 0) return EFAULT; + + result->length = len; return 0; } apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey, struct databuf *plain, struct databuf *cipher) { + int blksz = skey->cipher->block_size; apr_status_t err = EFAULT; EVP_CIPHER_CTX ctx = { 0 }; - HMAC_CTX hmac_ctx = { 0 }; - uint8_t rbuf[16]; - unsigned int len; + uint8_t rbuf[blksz]; + struct databuf hmacbuf; int outlen, totlen; int ret; @@ -80,12 +124,12 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey, /* confounder to avoid exposing random numbers directly to clients * as IVs */ - ret = RAND_bytes(rbuf, 16); - if (ret == 0) goto done; + ret = apr_generate_random_bytes(rbuf, sizeof(rbuf)); + if (ret != 0) goto done; if (cipher->length == 0) { /* add space for confounder and padding and MAC */ - cipher->length = (plain->length / 16 + 2) * 16; + cipher->length = (plain->length / blksz + 2) * blksz; cipher->value = apr_palloc(p, cipher->length + skey->md->md_size); if (!cipher->value) { err = ENOMEM; @@ -98,7 +142,7 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey, totlen = 0; outlen = cipher->length; - ret = EVP_EncryptUpdate(&ctx, cipher->value, &outlen, rbuf, 16); + ret = EVP_EncryptUpdate(&ctx, cipher->value, &outlen, rbuf, sizeof(rbuf)); if (ret == 0) goto done; totlen += outlen; @@ -114,24 +158,16 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey, totlen += outlen; /* now MAC the buffer */ - HMAC_CTX_init(&hmac_ctx); - - ret = HMAC_Init_ex(&hmac_ctx, skey->hkey, - skey->cipher->key_len, skey->md, NULL); - if (ret == 0) goto done; - - ret = HMAC_Update(&hmac_ctx, cipher->value, totlen); - if (ret == 0) goto done; + cipher->length = totlen; + hmacbuf.value = &cipher->value[totlen]; + ret = HMAC_BUFFER(skey, cipher, &hmacbuf); + if (ret != 0) goto done; - ret = HMAC_Final(&hmac_ctx, &cipher->value[totlen], &len); - if (ret == 0) goto done; - - cipher->length = totlen + len; + cipher->length += hmacbuf.length; err = 0; done: EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hmac_ctx); return err; } @@ -140,29 +176,19 @@ apr_status_t UNSEAL_BUFFER(apr_pool_t *p, struct seal_key *skey, { apr_status_t err = EFAULT; EVP_CIPHER_CTX ctx = { 0 }; - HMAC_CTX hmac_ctx = { 0 }; unsigned char mac[skey->md->md_size]; - unsigned int len; + struct databuf hmacbuf; int outlen, totlen; volatile bool equal = true; int ret, i; /* check MAC first */ - HMAC_CTX_init(&hmac_ctx); - - ret = HMAC_Init_ex(&hmac_ctx, skey->hkey, - skey->cipher->key_len, skey->md, NULL); - if (ret == 0) goto done; - cipher->length -= skey->md->md_size; + hmacbuf.value = mac; + ret = HMAC_BUFFER(skey, cipher, &hmacbuf); + if (ret != 0) goto done; - ret = HMAC_Update(&hmac_ctx, cipher->value, cipher->length); - if (ret == 0) goto done; - - ret = HMAC_Final(&hmac_ctx, mac, &len); - if (ret == 0) goto done; - - if (len != skey->md->md_size) goto done; + if (hmacbuf.length != skey->md->md_size) goto done; for (i = 0; i < skey->md->md_size; i++) { if (cipher->value[cipher->length + i] != mac[i]) equal = false; /* not breaking intentionally, @@ -197,14 +223,22 @@ apr_status_t UNSEAL_BUFFER(apr_pool_t *p, struct seal_key *skey, totlen += outlen; /* now remove the confounder */ - totlen -= 16; - memmove(plain->value, plain->value + 16, totlen); + totlen -= skey->cipher->block_size; + memmove(plain->value, plain->value + skey->cipher->block_size, totlen); plain->length = totlen; err = 0; done: EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hmac_ctx); return err; } + +int get_mac_size(struct seal_key *skey) +{ + if (skey) { + return skey->md->md_size; + } else { + return 0; + } +}