memcpy(sign_buff, server->sign_last, 8);
}
+int sign_verify_reply(struct ncp_server *server, const char *packet, size_t size, __u32 totalsize, const void *sign_buff) {
+ unsigned char data[64];
+ unsigned char hash[16];
+
+ memcpy(data, server->sign_root, 8);
+ *(__u32*)(data + 8) = totalsize;
+ if (size < 52) {
+ memcpy(data + 12, packet, size);
+ memset(data + 12 + size, 0, 52 - size);
+ } else {
+ memcpy(data + 12, packet, 52);
+ }
+ nwsign(server->sign_last, data, hash);
+ return memcmp(sign_buff, hash, 8);
+}
+
#endif /* CONFIG_NCPFS_PACKET_SIGNING */
#ifdef CONFIG_NCPFS_PACKET_SIGNING
void __sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff);
+int sign_verify_reply(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, const void *sign_buff);
#endif
static inline size_t sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff) {
if (result < 8 + 8) {
result = -EIO;
} else {
+ unsigned int hdrl;
+
result -= 8;
+ hdrl = sock->sk->family == AF_INET ? 8 : 6;
+ if (sign_verify_reply(server, ((char*)req->reply_buf) + hdrl, result - hdrl, cpu_to_le32(result), ((char*)req->reply_buf) + result)) {
+ printk(KERN_INFO "ncpfs: Signature violation\n");
+ result = -EIO;
+ }
}
}
#endif
return -EIO;
}
}
+#ifdef CONFIG_NCPFS_PACKET_SIGNING
+ if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
+ if (sign_verify_reply(server, (unsigned char*)(req->reply_buf) + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) {
+ printk(KERN_ERR "ncpfs: tcp: Signature violation\n");
+ __ncp_abort_request(server, req, -EIO);
+ return -EIO;
+ }
+ }
+#endif
ncp_finish_request(req, req->datalen);
nextreq:;
__ncp_next_request(server);