1d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: roaming_common.c,v 1.13 2015/01/27 12:54:06 okan Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2004-2009 AppGate Network Security AB 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Permission to use, copy, modify, and distribute this software for any 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * purpose with or without fee is hereby granted, provided that the above 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * copyright notice and this permission notice appear in all copies. 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/socket.h> 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/uio.h> 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <errno.h> 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "atomicio.h" 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "packet.h" 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "xmalloc.h" 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "cipher.h" 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "buffer.h" 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "roaming.h" 36d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "digest.h" 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic size_t out_buf_size = 0; 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic char *out_buf = NULL; 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic size_t out_start; 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic size_t out_last; 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic u_int64_t write_bytes = 0; 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic u_int64_t read_bytes = 0; 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint roaming_enabled = 0; 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint resume_in_progress = 0; 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 50d059297112922cabb0c674840589be8db821fd9aAdam Langleyget_snd_buf_size(void) 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int fd = packet_get_connection_out(); 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int optval; 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman socklen_t optvallen = sizeof(optval); 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0) 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman optval = DEFAULT_ROAMBUF; 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return optval; 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 62d059297112922cabb0c674840589be8db821fd9aAdam Langleyget_recv_buf_size(void) 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int fd = packet_get_connection_in(); 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int optval; 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman socklen_t optvallen = sizeof(optval); 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0) 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman optval = DEFAULT_ROAMBUF; 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return optval; 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanset_out_buffer_size(size_t size) 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 76d059297112922cabb0c674840589be8db821fd9aAdam Langley if (size == 0 || size > MAX_ROAMBUF) 77d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: bad buffer size %lu", __func__, (u_long)size); 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * The buffer size can only be set once and the buffer will live 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * as long as the session lives. 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (out_buf == NULL) { 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_buf_size = size; 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_buf = xmalloc(size); 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_start = 0; 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_last = 0; 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanu_int64_t 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanget_recv_bytes(void) 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return read_bytes; 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanadd_recv_bytes(u_int64_t num) 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman read_bytes += num; 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanu_int64_t 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanget_sent_bytes(void) 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return write_bytes; 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanroam_set_bytes(u_int64_t sent, u_int64_t recvd) 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman read_bytes = recvd; 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman write_bytes = sent; 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic void 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanbuf_append(const char *buf, size_t count) 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (count > out_buf_size) { 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buf += count - out_buf_size; 120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman count = out_buf_size; 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (count < out_buf_size - out_last) { 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memcpy(out_buf + out_last, buf, count); 124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (out_start > out_last) 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_start += count; 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_last += count; 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* data will wrap */ 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman size_t chunk = out_buf_size - out_last; 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memcpy(out_buf + out_last, buf, chunk); 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memcpy(out_buf, buf + chunk, count - chunk); 132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_last = count - chunk; 133bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman out_start = out_last + 1; 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanssize_t 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanroaming_write(int fd, const void *buf, size_t count, int *cont) 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssize_t ret; 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 142bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ret = write(fd, buf, count); 143bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ret > 0 && !resume_in_progress) { 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman write_bytes += ret; 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (out_buf_size > 0) 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buf_append(buf, ret); 147bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 148bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (out_buf_size > 0 && 149bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (ret == 0 || (ret == -1 && errno == EPIPE))) { 150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (wait_for_roaming_reconnect() != 0) { 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ret = 0; 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *cont = 1; 153bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ret = -1; 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman errno = EAGAIN; 156bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 157bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ret; 159bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 160bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 161bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanssize_t 162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanroaming_read(int fd, void *buf, size_t count, int *cont) 163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssize_t ret = read(fd, buf, count); 165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ret > 0) { 166bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!resume_in_progress) { 167bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman read_bytes += ret; 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 169bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else if (out_buf_size > 0 && 170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (ret == 0 || (ret == -1 && (errno == ECONNRESET 171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman || errno == ECONNABORTED || errno == ETIMEDOUT 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman || errno == EHOSTUNREACH)))) { 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("roaming_read failed for %d ret=%ld errno=%d", 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd, (long)ret, errno); 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ret = 0; 176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (wait_for_roaming_reconnect() == 0) 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *cont = 1; 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ret; 180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 181bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmansize_t 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanroaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf, 184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman size_t count) 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman size_t ret = atomicio(f, fd, buf, count); 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (f == vwrite && ret > 0 && !resume_in_progress) { 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman write_bytes += ret; 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else if (f == read && ret > 0 && !resume_in_progress) { 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman read_bytes += ret; 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ret; 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanresend_bytes(int fd, u_int64_t *offset) 198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman size_t available, needed; 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (out_start < out_last) 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman available = out_last - out_start; 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman available = out_buf_size; 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman needed = write_bytes - *offset; 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("resend_bytes: resend %lu bytes from %llu", 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (unsigned long)needed, (unsigned long long)*offset); 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (needed > available) 209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Needed to resend more data than in the cache"); 210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (out_last < needed) { 211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int chunkend = needed - out_last; 212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman atomicio(vwrite, fd, out_buf + out_buf_size - chunkend, 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman chunkend); 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman atomicio(vwrite, fd, out_buf, out_last); 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman atomicio(vwrite, fd, out_buf + (out_last - needed), needed); 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Caclulate a new key after a reconnect 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmancalculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 226d059297112922cabb0c674840589be8db821fd9aAdam Langley u_char hash[SSH_DIGEST_MAX_LENGTH]; 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Buffer b; 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_init(&b); 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_int64(&b, *key); 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_int64(&b, cookie); 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_int64(&b, challenge); 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 234d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, hash, sizeof(hash)) != 0) 235d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: digest_buffer failed", __func__); 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_clear(&b); 238d059297112922cabb0c674840589be8db821fd9aAdam Langley buffer_append(&b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); 239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *key = buffer_get_int64(&b); 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 242