aboutsummaryrefslogtreecommitdiffstats
path: root/package/utils/uencrypt/src
Commit message (Collapse)AuthorAgeFilesLines
* uencrypt: split common and library-specific codeEneas U de Queiroz2023-03-175-293/+379
| | | | | | | | | | | | | | This splits the code in 4 files: - uencrypt.h - uencrypt.c - main program - uencrypt-openssl.c - OpenSSL/wolfSSL implementation - uencrypt-mbedtls - mbedTLS implementation Other changes, accounting for ~400 bytes increase in ipk size: - more error condition checking and reporting, - hide key and iv command line arguments Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
* uencrypt: add support for mbedtlsEneas U de Queiroz2023-03-173-26/+258
| | | | | | | | | | | | | | This commit includes some additional changes: - better handling of iv and keys in openssl/wolfssl variants - fix compiler warnings and whitespace - build all 3 variants as separate packages - adjust the new package name in targets' DEVICE_PACKAGES - remove PKG_FLAGS:=nonshared [Beeline SmartBox Flash - OK] Tested-by: Mikhail Zhilkin <csharper2005@gmail.com> [after test: replaced a hardcoded IV size of 16 by cipher_info->iv_size] Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
* uencrypt: support all available ciphersNick French2022-08-191-11/+44
| | | | | | | | | | | | | Modify uencrypt to support any cipher provided by ssl library. Original tool supported only AES-128-CBC to decrypt the config mtd of Arcadyan WG430223/WG443223. TP-Link Deco S4 has mtd configuration encrypted with DES-ECB, so make the cipher generic to support both routers. Signed-off-by: Nick French <nickfrench@gmail.com> Reviewed-by: Eneas U de Queiroz >cotequeiroz@gmail.com>
* uencrypt: add package to decrypt WG4хх223 configEneas U de Queiroz2022-07-192-0/+137
This adds a simple AES-128-CBC encryption/decryption program using either wolfSSL or OpenSSL as backend to decrypt Arcadyan WG4xx223 configuration partitions. The ipk size is 3,355 bytes. Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
158' href='#n158'>158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
/* Minimal PCI driver for Mini-OS. 
 * Copyright (c) 2007-2008 Samuel Thibault.
 * Based on blkfront.c.
 */

#include <os.h>
#include <xenbus.h>
#include <events.h>
#include <errno.h>
#include <gnttab.h>
#include <xmalloc.h>
#include <wait.h>
#include <pcifront.h>

#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))

DECLARE_WAIT_QUEUE_HEAD(pcifront_queue);

struct pcifront_dev {
    domid_t dom;

    struct xen_pci_sharedinfo *info;
    grant_ref_t info_ref;
    evtchn_port_t evtchn;

    char *nodename;
    char *backend;

    xenbus_event_queue events;
};

void pcifront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
{
    wake_up(&pcifront_queue);
}

static void free_pcifront(struct pcifront_dev *dev)
{
    mask_evtchn(dev->evtchn);

    free(dev->backend);

    gnttab_end_access(dev->info_ref);
    free_page(dev->info);

    unbind_evtchn(dev->evtchn);

    free(dev->nodename);
    free(dev);
}

struct pcifront_dev *init_pcifront(char *_nodename)
{
    xenbus_transaction_t xbt;
    char* err;
    char* message=NULL;
    int retry=0;
    char* msg;
    char* nodename = _nodename ? _nodename : "device/pci/0";
    int dom;

    struct pcifront_dev *dev;

    char path[strlen(nodename) + 1 + 10 + 1];

    printk("******************* PCIFRONT for %s **********\n\n\n", nodename);

    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    dom = xenbus_read_integer(path); 
    if (dom == -1) {
        printk("no backend\n");
        return NULL;
    }

    dev = malloc(sizeof(*dev));
    memset(dev, 0, sizeof(*dev));
    dev->nodename = strdup(nodename);
    dev->dom = dom;

    evtchn_alloc_unbound(dev->dom, pcifront_handler, dev, &dev->evtchn);

    dev->info = (struct xen_pci_sharedinfo*) alloc_page();
    memset(dev->info,0,PAGE_SIZE);

    dev->info_ref = gnttab_grant_access(dev->dom,virt_to_mfn(dev->info),0);

    dev->events = NULL;

again:
    err = xenbus_transaction_start(&xbt);
    if (err) {
        printk("starting transaction\n");
    }

    err = xenbus_printf(xbt, nodename, "pci-op-ref","%u",
                dev->info_ref);
    if (err) {
        message = "writing pci-op-ref";
        goto abort_transaction;
    }
    err = xenbus_printf(xbt, nodename,
                "event-channel", "%u", dev->evtchn);
    if (err) {
        message = "writing event-channel";
        goto abort_transaction;
    }
    err = xenbus_printf(xbt, nodename,
                "magic", XEN_PCI_MAGIC);
    if (err) {
        message = "writing magic";
        goto abort_transaction;
    }

    err = xenbus_printf(xbt, nodename, "state", "%u",
            3); /* initialised */


    err = xenbus_transaction_end(xbt, 0, &retry);
    if (retry) {
            goto again;
        printk("completing transaction\n");
    }

    goto done;

abort_transaction:
    xenbus_transaction_end(xbt, 1, &retry);
    goto error;

done:

    snprintf(path, sizeof(path), "%s/backend", nodename);
    msg = xenbus_read(XBT_NIL, path, &dev->backend);
    if (msg) {
        printk("Error %s when reading the backend path %s\n", msg, path);
        goto error;
    }

    printk("backend at %s\n", dev->backend);

    {
        char path[strlen(dev->backend) + 1 + 5 + 1];
        snprintf(path, sizeof(path), "%s/state", dev->backend);

        xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);

        xenbus_wait_for_value(path, "4", &dev->events);

        xenbus_printf(xbt, nodename, "state", "%u", 4); /* connected */
    }
    unmask_evtchn(dev->evtchn);

    printk("**************************\n");

    return dev;

error:
    free_pcifront(dev);
    return NULL;
}

void pcifront_scan(struct pcifront_dev *dev, void (*func)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun))
{
    char path[strlen(dev->backend) + 1 + 5 + 10 + 1];
    int i, n;
    char *s, *msg;
    unsigned int domain, bus, slot, fun;

    snprintf(path, sizeof(path), "%s/num_devs", dev->backend);
    n = xenbus_read_integer(path);

    for (i = 0; i < n; i++) {
        snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i);
        msg = xenbus_read(XBT_NIL, path, &s);
        if (msg) {
            printk("Error %s when reading the PCI root name at %s\n", path);
            continue;
        }

        if (sscanf(s, "%x:%x:%x.%x", &domain, &bus, &slot, &fun) != 4) {
            printk("\"%s\" does not look like a PCI device address\n", s);
            free(s);
            continue;
        }
        free(s);

        func(domain, bus, slot, fun);
    }
}

void shutdown_pcifront(struct pcifront_dev *dev)
{
    char* err;
    char *nodename = dev->nodename;

    char path[strlen(dev->backend) + 1 + 5 + 1];

    printk("close pci: backend at %s\n",dev->backend);

    snprintf(path, sizeof(path), "%s/state", dev->backend);
    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
    xenbus_wait_for_value(path, "5", &dev->events);

    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
    xenbus_wait_for_value(path, "6", &dev->events);

    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    xenbus_wait_for_value(path, "2", &dev->events);

    xenbus_unwatch_path(XBT_NIL, path);

    snprintf(path, sizeof(path), "%s/info-ref", nodename);
    xenbus_rm(XBT_NIL, path);
    snprintf(path, sizeof(path), "%s/event-channel", nodename);
    xenbus_rm(XBT_NIL, path);

    free_pcifront(dev);
}


void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op)
{
    dev->info->op = *op;
    /* Make sure info is written before the flag */
    wmb();
    set_bit(_XEN_PCIF_active, (void*) &dev->info->flags);
    notify_remote_via_evtchn(dev->evtchn);

    wait_event(pcifront_queue, !test_bit(_XEN_PCIF_active, (void*) &dev->info->flags));

    /* Make sure flag is read before info */
    rmb();
    *op = dev->info->op;
}

int pcifront_conf_read(struct pcifront_dev *dev,
                       unsigned int dom,
                       unsigned int bus, unsigned int slot, unsigned long fun,
                       unsigned int off, unsigned int size, unsigned int *val)
{
    struct xen_pci_op op;

    memset(&op, 0, sizeof(op));

    op.cmd = XEN_PCI_OP_conf_read;
    op.domain = dom;
    op.bus = bus;
    op.devfn = PCI_DEVFN(slot, fun);
    op.offset = off;
    op.size = size;

    pcifront_op(dev, &op);

    if (op.err)
        return op.err;

    *val = op.value;

    return 0;
}

int pcifront_conf_write(struct pcifront_dev *dev,
                        unsigned int dom,
                        unsigned int bus, unsigned int slot, unsigned long fun,
                        unsigned int off, unsigned int size, unsigned int val)
{
    struct xen_pci_op op;

    memset(&op, 0, sizeof(op));

    op.cmd = XEN_PCI_OP_conf_write;
    op.domain = dom;
    op.bus = bus;
    op.devfn = PCI_DEVFN(slot, fun);
    op.offset = off;
    op.size = size;

    op.value = val;

    pcifront_op(dev, &op);

    return op.err;
}

int pcifront_enable_msi(struct pcifront_dev *dev,
                        unsigned int dom,
                        unsigned int bus, unsigned int slot, unsigned long fun)
{
    struct xen_pci_op op;

    memset(&op, 0, sizeof(op));

    op.cmd = XEN_PCI_OP_enable_msi;
    op.domain = dom;
    op.bus = bus;
    op.devfn = PCI_DEVFN(slot, fun);

    pcifront_op(dev, &op);
    
    if (op.err)
        return op.err;
    else
        return op.value;
}

int pcifront_disable_msi(struct pcifront_dev *dev,
                         unsigned int dom,
                         unsigned int bus, unsigned int slot, unsigned long fun)
{
    struct xen_pci_op op;

    memset(&op, 0, sizeof(op));

    op.cmd = XEN_PCI_OP_disable_msi;
    op.domain = dom;
    op.bus = bus;
    op.devfn = PCI_DEVFN(slot, fun);

    pcifront_op(dev, &op);
    
    return op.err;
}

int pcifront_enable_msix(struct pcifront_dev *dev,
                         unsigned int dom,
                         unsigned int bus, unsigned int slot, unsigned long fun,
                         struct xen_msix_entry *entries, int n)
{
    struct xen_pci_op op;

    if (n > SH_INFO_MAX_VEC)
        return XEN_PCI_ERR_op_failed;

    memset(&op, 0, sizeof(op));

    op.cmd = XEN_PCI_OP_enable_msix;
    op.domain = dom;
    op.bus = bus;
    op.devfn = PCI_DEVFN(slot, fun);
    op.value = n;

    memcpy(op.msix_entries, entries, n * sizeof(*entries));

    pcifront_op(dev, &op);
    
    if (op.err)
        return op.err;

    memcpy(entries, op.msix_entries, n * sizeof(*entries));

    return 0;
}


int pcifront_disable_msix(struct pcifront_dev *dev,
                          unsigned int dom,
                          unsigned int bus, unsigned int slot, unsigned long fun)
{
    struct xen_pci_op op;

    memset(&op, 0, sizeof(op));

    op.cmd = XEN_PCI_OP_disable_msix;
    op.domain = dom;
    op.bus = bus;
    op.devfn = PCI_DEVFN(slot, fun);

    pcifront_op(dev, &op);
    
    return op.err;
}