Boolean ssh_virtual_adapter_param_decode(SshVirtualAdapterParams params, const unsigned char *data, size_t len) { unsigned char *dns; size_t dns_len; unsigned char *wins; size_t wins_len; unsigned char *win_domain; size_t win_domain_len; SshUInt32 netbios_node_type; SshUInt32 i; size_t decode_len; SSH_ASSERT(params != NULL); SSH_ASSERT(data != NULL); SSH_ASSERT(len > 0); memset(params, 0, sizeof(*params)); if (ssh_decode_array(data, len, SSH_DECODE_UINT32(¶ms->mtu), SSH_DECODE_UINT32(¶ms->dns_ip_count), SSH_DECODE_UINT32_STR_NOCOPY(&dns, &dns_len), SSH_DECODE_UINT32(¶ms->wins_ip_count), SSH_DECODE_UINT32_STR_NOCOPY(&wins, &wins_len), SSH_DECODE_UINT32_STR_NOCOPY( &win_domain, &win_domain_len), SSH_DECODE_UINT32(&netbios_node_type), SSH_FORMAT_END) != len) return FALSE; /* DNS. */ if (params->dns_ip_count) { params->dns_ip = ssh_calloc(params->dns_ip_count, sizeof(*params->dns_ip)); if (params->dns_ip == NULL) goto error; for (i = 0; i < params->dns_ip_count; i++) { decode_len = ssh_decode_ipaddr_array(dns, dns_len, ¶ms->dns_ip[i]); if (decode_len == 0) goto error; dns += decode_len; dns_len -= decode_len; } } /* WINS. */ if (params->wins_ip_count) { params->wins_ip = ssh_calloc(params->wins_ip_count, sizeof(*params->wins_ip)); if (params->wins_ip == NULL) goto error; for (i = 0; i < params->wins_ip_count; i++) { decode_len = ssh_decode_ipaddr_array(wins, wins_len, ¶ms->wins_ip[i]); if (decode_len == 0) goto error; wins += decode_len; wins_len -= decode_len; } } if (win_domain_len) { params->win_domain = ssh_memdup(win_domain, win_domain_len); if (params->win_domain == NULL) goto error; } params->netbios_node_type = (SshUInt8) netbios_node_type; return TRUE; error: ssh_free(params->dns_ip); ssh_free(params->wins_ip); ssh_free(params->win_domain); memset(params, 0, sizeof(*params)); return FALSE; }
void ssh_acc_device_modexp_op_done(SshCryptoStatus status, const unsigned char *data, size_t data_len, void *context) { SshAccDeviceModExpContext ctx = context; ctx->sub_op = NULL; if (status == SSH_CRYPTO_OK) { /* No array decoding is needed. */ (*ctx->callback)(SSH_CRYPTO_OK, data, data_len, ctx->context); ssh_acc_device_modexp_op_free(ctx); return; } else { unsigned char *b, *e, *m, *ret; size_t b_len, e_len, mod_len, ret_len; /* The accelerated operation has failed, instead perform the operation in software. */ SSH_DEBUG(SSH_D_FAIL, ("Accelerated modexp operation has failed, " "now performing the operation in software")); /* Decode the data buffer to extract the original parameters */ if (ssh_decode_array(ctx->data, ctx->data_len, SSH_DECODE_UINT32_STR_NOCOPY(&b, &b_len), SSH_DECODE_UINT32_STR_NOCOPY(&e, &e_len), SSH_DECODE_UINT32_STR_NOCOPY(&m, &mod_len), SSH_FORMAT_END) != ctx->data_len) { (*ctx->callback)(SSH_CRYPTO_NO_MEMORY, NULL, 0, ctx->context); ssh_acc_device_modexp_op_free(ctx); return; } ret_len = mod_len; if ((ret = ssh_calloc(1, ret_len)) == NULL) { (*ctx->callback)(SSH_CRYPTO_NO_MEMORY, NULL, 0, ctx->context); ssh_acc_device_modexp_op_free(ctx); return; } if (modexp_op_buf(ret, ret_len, b, b_len, e, e_len, m, mod_len)) { (*ctx->callback)(SSH_CRYPTO_OK, ret, ret_len, ctx->context); } else { (*ctx->callback)(SSH_CRYPTO_OPERATION_FAILED, NULL, 0, ctx->context); } ssh_acc_device_modexp_op_free(ctx); ssh_free(ret); return; } }